text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.convertTSLintDisableCommentsForProject = exports.createConvertToESLintConfig = void 0;
  const core_1 = require("@angular-devkit/core");
  const child_process_1 = require("child_process");
  const tmp_1 = require("tmp");
  const utils_1 = require("../utils");
  // eslint-disable-next-line @typescript-eslint/no-var-requires
  const tslintToEslintConfigVersion = require('../../package.json')
      .devDependencies['tslint-to-eslint-config'];
  let tslintToEslintConfigLibrary;
  function getTslintToEslintConfigLibrary(context) {
      if (tslintToEslintConfigLibrary) {
          return tslintToEslintConfigLibrary;
      }
      try {
          // This is usually not available at runtime but makes it easier to work with in our tests
          return require('tslint-to-eslint-config');
          // eslint-disable-next-line no-empty
      }
      catch (e) { }
      context.logger.info('\nINFO: We are now installing the "tslint-to-eslint-config" package into a tmp directory to aid with the conversion');
      context.logger.info('\nThis may take a minute or two...\n');
      /**
       * In order to avoid all users of angular-eslint needing to have tslint-to-eslint-config (and therefore tslint)
       * in their node_modules, we dynamically install and uninstall the library as part of the conversion
       * process.
       */
      const tempDir = tmp_1.dirSync().name;
      child_process_1.execSync(`npm i -D tslint-to-eslint-config@${tslintToEslintConfigVersion}`, {
          cwd: tempDir,
          stdio: 'ignore',
      });
      tslintToEslintConfigLibrary = require(require.resolve('tslint-to-eslint-config', {
          paths: [tempDir],
      }));
      return tslintToEslintConfigLibrary;
  }
  function createConvertToESLintConfig(context) {
      return async function convertToESLintConfig(pathToTslintJson, tslintJson) {
          const { findReportedConfiguration, createESLintConfiguration, joinConfigConversionResults, } = getTslintToEslintConfigLibrary(context);
          const reportedConfiguration = await findReportedConfiguration('npx tslint --print-config', pathToTslintJson);
          if (reportedConfiguration instanceof Error) {
              if (reportedConfiguration.message.includes('unknown option `--print-config')) {
                  throw new Error('\nError: TSLint v5.18 required in order to run this schematic. Please update your version and try again.\n');
              }
              /**
               * Make a print-config issue easier to understand for the end user.
               * This error could occur if, for example, the user does not have a TSLint plugin installed correctly that they
               * reference in their config.
               */
              const printConfigFailureMessageStart = 'Command failed: npx tslint --print-config "tslint.json"';
              if (reportedConfiguration.message.startsWith(printConfigFailureMessageStart)) {
                  throw new Error(`\nThere was a critical error when trying to inspect your tslint.json: \n${reportedConfiguration.message.replace(printConfigFailureMessageStart, '')}`);
              }
              throw new Error(`Unexpected error: ${reportedConfiguration.message}`);
          }
          const originalConfigurations = {
              tslint: {
                  full: reportedConfiguration,
                  raw: tslintJson,
              },
          };
          const summarizedConfiguration = await createESLintConfiguration(originalConfigurations);
          const expectedESLintPlugins = [
              // These are added to support the ng-cli-compat configs
              'eslint-plugin-jsdoc',
              'eslint-plugin-prefer-arrow',
              'eslint-plugin-import',
              // These are already covered by our recommended config, and are installed by the `ng add` schematic
              '@angular-eslint/eslint-plugin',
              '@angular-eslint/eslint-plugin-template',
          ];
          const convertedESLintConfig = joinConfigConversionResults(summarizedConfiguration, originalConfigurations);
          return {
              convertedESLintConfig,
              unconvertedTSLintRules: summarizedConfiguration.missing,
              ensureESLintPlugins: Array.from(summarizedConfiguration.plugins).filter((pluginName) => !expectedESLintPlugins.includes(pluginName)),
          };
      };
  }
  exports.createConvertToESLintConfig = createConvertToESLintConfig;
  function likelyContainsTSLintComment(fileContent) {
      return fileContent.includes('tslint:');
  }
  function convertTSLintDisableCommentsForProject(projectName) {
      return (tree, context) => {
          /**
           * We need to avoid a direct dependency on tslint-to-eslint-config
           * and ensure we are only resolving the dependency from the user's
           * node_modules on demand (it will be installed as part of the
           * conversion schematic).
           */
          const { convertFileComments } = getTslintToEslintConfigLibrary(context);
          const workspaceJson = utils_1.readJsonInTree(tree, 'angular.json');
          const existingProjectConfig = workspaceJson.projects[projectName];
          let pathRoot = '';
          // Default Angular CLI project at the root of the workspace
          if (existingProjectConfig.root === '') {
              pathRoot = 'src';
          }
          else {
              pathRoot = existingProjectConfig.root;
          }
          return utils_1.visitNotIgnoredFiles((filePath, host) => {
              if (!filePath.endsWith('.ts')) {
                  return;
              }
              const fileContent = host.read(filePath).toString('utf-8');
              // Avoid updating files if we don't have to
              if (!likelyContainsTSLintComment(fileContent)) {
                  return;
              }
              const updatedFileContent = convertFileComments({ fileContent, filePath });
              host.overwrite(filePath, updatedFileContent);
          }, core_1.normalize(pathRoot));
      };
  }
  exports.convertTSLintDisableCommentsForProject = convertTSLintDisableCommentsForProject;
  