import { writeFile } from './chunk-4SEZDGHZ.js';
import { __name } from './chunk-6AXVLTU5.js';
import { parseAsync, Lang } from '@ast-grep/napi';
import { LogLevelLabel } from '@storm-software/config-tools/types';
import { readJsonFile } from '@stryke/fs/read-file';
import { deepClone } from '@stryke/helpers/deep-clone';
import { isEqual } from '@stryke/helpers/is-equal';
import { Mutex } from '@stryke/helpers/mutex';
import { StormJSON } from '@stryke/json/storm-json';
import { joinPaths } from '@stryke/path/join-paths';
import defu from 'defu';
import { existsSync } from 'node:fs';

var mutex = new Mutex();
function getLatestErrorCode(type = "general", errorCodes = {}) {
  if (!errorCodes[type]) {
    return "1";
  }
  const keys = Object.keys(errorCodes[type]);
  if (keys.length === 0) {
    return "1";
  }
  const errorCode = Number.parseInt(keys.sort((a, b) => b.localeCompare(a))[0]);
  if (Number.isNaN(errorCode)) {
    return "1";
  }
  return String(errorCode + 1);
}
__name(getLatestErrorCode, "getLatestErrorCode");
async function transformErrors(log, source, context) {
  const errorCodesFilePath = joinPaths(context.workspaceConfig.workspaceRoot, context.options.errorsFile);
  let errorCodes = {};
  if (!existsSync(errorCodesFilePath)) {
    log(LogLevelLabel.WARN, `No error codes file path exists. Writing empty file.`);
    await writeFile(log, errorCodesFilePath, StormJSON.stringify({}));
  } else {
    errorCodes = await readJsonFile(errorCodesFilePath);
  }
  const originalErrorCodes = deepClone(errorCodes);
  const ast = await parseAsync(Lang.TypeScript, source.code.toString());
  const root = ast.root();
  const nodes = root.findAll({
    rule: {
      kind: "new_expression",
      any: [
        {
          pattern: "new Error($$$ARGS)"
        },
        {
          pattern: "new TypeError($$$ARGS)"
        },
        {
          pattern: "new ReferenceError($$$ARGS)"
        },
        {
          pattern: "new SyntaxError($$$ARGS)"
        },
        {
          pattern: "new RangeError($$$ARGS)"
        },
        {
          pattern: "new EvalError($$$ARGS)"
        },
        {
          pattern: "new URIError($$$ARGS)"
        },
        {
          pattern: "new AggregateError($$$ARGS)"
        },
        {
          pattern: "new InternalError($$$ARGS)"
        },
        {
          pattern: "new SystemError($$$ARGS)"
        },
        {
          pattern: "new NotImplementedError($$$ARGS)"
        },
        {
          pattern: "new StormError($$$ARGS)"
        }
      ]
    }
  });
  if (!nodes || nodes.length === 0) {
    log(LogLevelLabel.TRACE, `No error messages require transformation in ${source.id}.`);
    return source;
  }
  for (const node of nodes) {
    const args = node.getMultipleMatches("ARGS").filter((arg) => arg.kind() === "string" || arg.kind() === "template_string");
    if (args.length >= 1 && args[0]) {
      let message = "";
      const params = [];
      if (args[0].kind() === "string") {
        message = args[0].text().slice(1, -1);
      } else if (args[0].kind() === "template_string") {
        for (const node2 of args[0].children()) {
          if (node2.kind() === "string_fragment") {
            message += node2.text();
          } else if (node2.kind() === "template_substitution") {
            const param = node2.text().slice(2, -1);
            if (param) {
              params.push(param);
              message += "%s";
            }
          }
        }
      }
      if (message) {
        let type = "general";
        if (args.length > 1 && args[1]) {
          const text = args[1].text();
          if (text) {
            type = text;
          }
        }
        errorCodes[type] ??= {};
        let code = Object.keys(errorCodes[type] ?? {}).find((key) => errorCodes[type]?.[key] === message);
        if (!code) {
          code = getLatestErrorCode(type, errorCodes);
          log(LogLevelLabel.INFO, `Found unlisted error message "${message}" in ${source.id}. Assigning it to "${type}" code #${code}.`);
          errorCodes[type] ??= {};
          errorCodes[type][code] = message;
        }
        source.code = source.code.replaceAll(node.text(), `new StormError({ type: "${type}", code: ${code}${params.length > 0 ? ` params: [${params.join(", ")}] ` : ""} })`);
      }
    }
  }
  if (!isEqual(originalErrorCodes, errorCodes)) {
    log(LogLevelLabel.INFO, `Adding error messages from ${source.id} to ${context.options.errorsFile}.`);
    await mutex.acquire();
    try {
      await writeFile(log, errorCodesFilePath, StormJSON.stringify(defu(errorCodes, await readJsonFile(errorCodesFilePath))));
    } finally {
      mutex.release();
    }
  }
  return source;
}
__name(transformErrors, "transformErrors");

export { transformErrors };
//# sourceMappingURL=chunk-AIBU7K67.js.map
//# sourceMappingURL=chunk-AIBU7K67.js.map