'use strict';

var chunk6MFRUH4E_cjs = require('./chunk-6MFRUH4E.cjs');
var chunkYANASJV2_cjs = require('./chunk-YANASJV2.cjs');
var chunk2ITILIBC_cjs = require('./chunk-2ITILIBC.cjs');
var chunkUJJENY47_cjs = require('./chunk-UJJENY47.cjs');
var chunkAF3E2D32_cjs = require('./chunk-AF3E2D32.cjs');
var types = require('@storm-software/config-tools/types');
var packageFns = require('@stryke/fs/package-fns');
var readFile = require('@stryke/fs/read-file');
var semverFns = require('@stryke/fs/semver-fns');
var filePathFns = require('@stryke/path/file-path-fns');
var getParentPath = require('@stryke/path/get-parent-path');
var isFile = require('@stryke/path/is-file');
var joinPaths = require('@stryke/path/join-paths');
var isError = require('@stryke/type-checks/is-error');
var path = require('path');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var path__default = /*#__PURE__*/_interopDefault(path);

var VALID_SEVERITY = [
  "off",
  "warn",
  "error"
];
function isValidSeverity(severity) {
  return VALID_SEVERITY.includes(severity);
}
chunkAF3E2D32_cjs.__name(isValidSeverity, "isValidSeverity");
async function writeOutputFile(log, outputFile, outputData) {
  const filePath = path__default.default.resolve(process.cwd(), outputFile);
  if (isFile.isDirectory(filePath)) {
    log(types.LogLevelLabel.ERROR, `Cannot write to output file path, it is a directory: ${filePath}`);
  } else {
    try {
      await chunkUJJENY47_cjs.writeFile(log, filePath, outputData);
      log(types.LogLevelLabel.INFO, `The output file has been created: ${filePath}`);
    } catch (err) {
      log(types.LogLevelLabel.ERROR, `There was a problem writing the output file: ${filePath}`);
      console.error(err);
    }
  }
}
chunkAF3E2D32_cjs.__name(writeOutputFile, "writeOutputFile");
async function hasEslintConfiguration(eslintFile, packageJsonConfig) {
  const configObject = {
    exists: false,
    emptyEslint: false,
    emptyPkgJsonConfig: false
  };
  if (eslintFile) {
    const content = await readFile.readFile(eslintFile).then((txt) => txt.trim().replace(/\n/g, ""), () => null);
    if (content === "" || content === "{}" || content === "---" || content === "module.exports = {}") {
      configObject.emptyEslint = true;
    } else {
      configObject.exists = true;
    }
  } else if (packageJsonConfig?.eslintConfig) {
    if (Object.keys(packageJsonConfig.eslintConfig).length) {
      configObject.exists = true;
    } else {
      configObject.emptyPkgJsonConfig = true;
    }
  }
  return configObject;
}
chunkAF3E2D32_cjs.__name(hasEslintConfiguration, "hasEslintConfiguration");
async function lint(log, context, eslintrcFile, { lintDuringBuild = false, eslintOptions = null, reportErrorsOnly = false, maxWarnings = -1, formatter = null, outputFile = null }) {
  try {
    await chunk2ITILIBC_cjs.installPackages(log, context, [
      {
        name: "eslint",
        dev: true
      },
      {
        name: "eslint-config-storm-stack",
        dev: true
      }
    ]);
    const isInstalled = packageFns.isPackageExists("eslint", {
      paths: [
        context.workspaceConfig.workspaceRoot,
        context.projectRoot
      ]
    });
    if (!isInstalled) {
      log(types.LogLevelLabel.ERROR, `ESLint must be installed${lintDuringBuild ? " in order to run during builds:" : ":"} npm install --save-dev eslint`);
      return null;
    }
    const module = await context.resolver.import(context.resolver.esmResolve("eslint"));
    const useFlatConfig = eslintrcFile ? filePathFns.findFileName(eslintrcFile).startsWith("eslint.config.") : false;
    let ESLint;
    if ("loadESLint" in module) {
      ESLint = await module.loadESLint({
        useFlatConfig
      });
    }
    const eslintVersion = semverFns.parseVersion(ESLint?.version);
    if (!eslintVersion || eslintVersion.compare("8.57.0") < 0) {
      return `Error - Your project has an older version of ESLint installed${eslintVersion ? ` (${eslintVersion.major}.${eslintVersion.minor}.${eslintVersion.patch})` : ""}. Please upgrade to ESLint version 8.57.0 or above`;
    }
    const options = {
      useEslintrc: true,
      baseConfig: {},
      errorOnUnmatchedPattern: false,
      extensions: [
        ".js",
        ".jsx",
        ".ts",
        ".tsx"
      ],
      cache: true,
      ...eslintOptions
    };
    if (eslintVersion?.compare("9.0.0") && useFlatConfig) {
      for (const option of [
        "useEslintrc",
        "extensions",
        "ignorePath",
        "reportUnusedDisableDirectives",
        "resolvePluginsRelativeTo",
        "rulePaths",
        "inlineConfig",
        "maxWarnings"
      ]) {
        if (option in options) {
          delete options[option];
        }
      }
    }
    let eslint = new ESLint(options);
    let stormStackEslintPluginIsEnabled = false;
    const stormStackRulesEnabled = /* @__PURE__ */ new Map();
    for (const configFile of [
      eslintrcFile,
      joinPaths.joinPaths(context.projectRoot, "package.json")
    ]) {
      if (!configFile) continue;
      const completeConfig = await eslint.calculateConfigForFile(configFile);
      if (!completeConfig) continue;
      const plugins = completeConfig.plugins;
      const hasStormStackPlugin = (
        // in ESLint < 9, `plugins` value is string[]
        Array.isArray(plugins) ? plugins.includes("storm-stack") : "storm-stack" in plugins
      );
      if (hasStormStackPlugin) {
        stormStackEslintPluginIsEnabled = true;
        for (const [name, [severity]] of Object.entries(completeConfig.rules)) {
          if (!name.startsWith("storm-stack/")) {
            continue;
          }
          if (typeof severity === "number" && severity >= 0 && severity < VALID_SEVERITY.length) {
            stormStackRulesEnabled.set(name, VALID_SEVERITY[severity]);
          } else if (typeof severity === "string" && isValidSeverity(severity)) {
            stormStackRulesEnabled.set(name, severity);
          }
        }
        break;
      }
    }
    if (stormStackEslintPluginIsEnabled) {
      eslint = new ESLint(options);
    } else {
      log(types.LogLevelLabel.WARN, "The Storm Stack plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/app/api-reference/config/eslint#migrating-existing-config");
    }
    const lintStart = process.hrtime();
    let results = await eslint.lintFiles(context.resolvedTsconfig.fileNames.filter((fileName) => !fileName.includes(context.artifactsDir) && !fileName.includes("node_modules")));
    let selectedFormatter = null;
    if (options.fix) {
      await ESLint.outputFixes(results);
    }
    if (reportErrorsOnly) {
      results = ESLint.getErrorResults(results);
    }
    if (formatter) {
      selectedFormatter = await eslint.loadFormatter(formatter);
    }
    const formattedResult = await chunk6MFRUH4E_cjs.formatResults(
      context.projectRoot,
      results,
      // eslint-disable-next-line ts/unbound-method
      selectedFormatter?.format
    );
    const lintEnd = process.hrtime(lintStart);
    const totalWarnings = results.reduce((sum, file) => sum + file.warningCount, 0);
    if (outputFile) {
      await writeOutputFile(log, outputFile, formattedResult.output);
    }
    return {
      output: formattedResult.outputWithMessages,
      isError: ESLint.getErrorResults(results)?.length > 0 || maxWarnings >= 0 && totalWarnings > maxWarnings,
      eventInfo: {
        durationInSeconds: lintEnd[0],
        eslintVersion: eslintVersion.version,
        lintedFilesCount: results.length,
        lintFix: !!options.fix,
        eslintPluginErrorsCount: formattedResult.totalPluginErrorCount,
        eslintPluginWarningsCount: formattedResult.totalPluginWarningCount,
        stormStackRulesEnabled: Object.fromEntries(stormStackRulesEnabled)
      }
    };
  } catch (err) {
    if (lintDuringBuild) {
      log(types.LogLevelLabel.ERROR, `ESLint: ${isError.isError(err) && err.message ? err.message.replace(/\n/g, " ") : err}`);
      return null;
    } else {
      throw err;
    }
  }
}
chunkAF3E2D32_cjs.__name(lint, "lint");
async function runLintCheck(log, context, opts) {
  const { lintDuringBuild = false, eslintOptions = null, reportErrorsOnly = false, maxWarnings = -1, formatter = null, outputFile = null, type = "recommended" } = opts;
  const eslintFile = getParentPath.getParentPath([
    // eslint v9
    "eslint.config.js",
    "eslint.config.mjs",
    "eslint.config.cjs",
    // TS extensions require to install a separate package `jiti`.
    // https://eslint.org/docs/latest/use/configure/configuration-files#typescript-configuration-files
    "eslint.config.ts",
    "eslint.config.mts",
    "eslint.config.cts",
    // eslint <= v8
    ".eslintrc.js",
    ".eslintrc.cjs",
    ".eslintrc.yaml",
    ".eslintrc.yml",
    ".eslintrc.json",
    ".eslintrc"
  ], context.projectRoot) ?? null;
  const config = await hasEslintConfiguration(eslintFile, context.packageJson);
  if (config.exists) {
    return lint(log, context, eslintFile, {
      lintDuringBuild,
      eslintOptions,
      reportErrorsOnly,
      maxWarnings,
      formatter,
      outputFile
    });
  }
  if (lintDuringBuild) {
    if (config.emptyPkgJsonConfig || config.emptyEslint) {
      log(types.LogLevelLabel.WARN, `No ESLint configuration detected. Run "storm-stack lint" to begin setup`);
    }
    return null;
  } else {
    const isEslintInstalled = packageFns.isPackageExists("eslint", {
      paths: [
        context.workspaceConfig.workspaceRoot,
        context.projectRoot
      ]
    });
    const isEslintPluginInstalled = packageFns.isPackageExists("eslint-config-storm-stack", {
      paths: [
        context.workspaceConfig.workspaceRoot,
        context.projectRoot
      ]
    });
    if (!isEslintInstalled || !isEslintPluginInstalled) {
      await chunk2ITILIBC_cjs.installPackages(log, context, [
        {
          name: "eslint",
          dev: true
        },
        {
          name: "eslint-config-storm-stack",
          dev: true
        }
      ]);
    }
    await chunkYANASJV2_cjs.writeDefaultEslintConfig(log, context, type);
  }
  log(types.LogLevelLabel.SUCCESS, `ESLint has successfully been configured. Run "storm-stack lint" again to view warnings and errors.`);
  return null;
}
chunkAF3E2D32_cjs.__name(runLintCheck, "runLintCheck");

exports.runLintCheck = runLintCheck;
//# sourceMappingURL=chunk-N72GV5HY.cjs.map
//# sourceMappingURL=chunk-N72GV5HY.cjs.map