// src/actions/packman/lint.ts
import {
  existsSync as existsSync3,
  readFileSync as readFileSync2,
  writeFileSync
} from "node:fs";
import PATH2 from "node:path";
import chalk2 from "chalk";

// src/pm/workspaces.ts
import { existsSync, readFileSync } from "node:fs";
import PATH from "node:path";
import { globSync } from "glob";
function readJsonFile(path) {
  if (!existsSync(path)) return void 0;
  try {
    return JSON.parse(readFileSync(path, "utf8"));
  } catch {
    return void 0;
  }
}
function readRootPackageJson(cwd = process.cwd()) {
  return readJsonFile(PATH.resolve(cwd, "package.json"));
}
function detectPackageManagerFromPackageJson(cwd = process.cwd()) {
  const packageManager = readRootPackageJson(cwd)?.packageManager;
  if (!packageManager) return void 0;
  return packageManager.split("@")[0];
}

// src/pm/detectPackageManager.ts
import { existsSync as existsSync2 } from "node:fs";
var knownPackageManagers = /* @__PURE__ */ new Set(["bun", "npm", "pnpm", "yarn"]);
function detectPackageManager() {
  const packageManager = detectPackageManagerFromPackageJson();
  if (packageManager && knownPackageManagers.has(packageManager)) {
    return packageManager;
  }
  if (existsSync2("pnpm-lock.yaml") || existsSync2("pnpm-workspace.yaml")) return "pnpm";
  if (existsSync2("bun.lock") || existsSync2("bun.lockb")) return "bun";
  if (existsSync2("yarn.lock") || existsSync2(".yarnrc.yml")) return "yarn";
  if (existsSync2("package-lock.json") || existsSync2("npm-shrinkwrap.json")) return "npm";
  return "yarn";
}

// src/lib/loadConfig.ts
import chalk from "chalk";
import { cosmiconfig } from "cosmiconfig";
import { TypeScriptLoader } from "cosmiconfig-typescript-loader";
import deepmerge from "deepmerge";
var config;
var rootConfigPath;
function createExplorer() {
  return cosmiconfig("xy", { cache: true, loaders: { ".ts": TypeScriptLoader() } });
}
var loadConfig = async (params) => {
  if (config === void 0) {
    const cosmicConfigResult = await createExplorer().search();
    config = cosmicConfigResult?.config ?? {};
    rootConfigPath = cosmicConfigResult?.filepath;
    const configFilePath = cosmicConfigResult?.filepath;
    if (configFilePath !== void 0) {
      console.log(chalk.green(`Loaded config from ${configFilePath}`));
      if (config.verbose) {
        console.log(chalk.gray(`${JSON.stringify(config, null, 2)}`));
      }
    }
  }
  return deepmerge(config, params ?? {});
};

// src/actions/packman/lint.ts
var DEFAULT_MINIMUM_RELEASE_AGE = 4320;
var DEFAULT_RELEASE_AGE_EXCLUDES = ["'@xylabs/*'", "'@xyo-network/*'"];
function resolvePackmanConfig(cfg) {
  return {
    minimumReleaseAge: cfg?.minimumReleaseAge ?? DEFAULT_MINIMUM_RELEASE_AGE,
    minimumReleaseAgeExclude: cfg?.minimumReleaseAgeExclude ?? DEFAULT_RELEASE_AGE_EXCLUDES
  };
}
function readPnpmWorkspaceYaml(cwd) {
  const wsPath = PATH2.join(cwd, "pnpm-workspace.yaml");
  if (!existsSync3(wsPath)) return void 0;
  return readFileSync2(wsPath, "utf8");
}
function writePnpmWorkspaceYaml(cwd, content) {
  writeFileSync(PATH2.join(cwd, "pnpm-workspace.yaml"), content, "utf8");
}
function parseYamlListSection(content, sectionName) {
  const items = [];
  let inSection = false;
  for (const line of content.split("\n")) {
    if (new RegExp(String.raw`^${sectionName}\s*:`).test(line)) {
      inSection = true;
      continue;
    }
    if (inSection) {
      const match = /^\s+-\s+(.+)$/.exec(line);
      if (match) {
        items.push(match[1].trim());
      } else if (line.trim() && !/^\s/.test(line)) {
        break;
      }
    }
  }
  return items;
}
function checkEnableScripts(cwd, verbose, silent) {
  const yarnrcPath = PATH2.join(cwd, ".yarnrc.yml");
  if (!existsSync3(yarnrcPath)) {
    if (verbose) console.log(chalk2.gray("  No .yarnrc.yml found, skipping enableScripts check"));
    return true;
  }
  const content = readFileSync2(yarnrcPath, "utf8");
  for (const line of content.split("\n")) {
    const trimmed = line.trim();
    if (/^enableScripts\s*:/.test(trimmed)) {
      const value = trimmed.replace(/^enableScripts\s*:\s*/, "").trim();
      if (value === "false") {
        if (verbose) console.log(chalk2.green("  enableScripts is correctly set to false"));
        return true;
      }
      if (!silent) console.log(chalk2.red("  enableScripts is set to", value, "(expected false)"));
      return false;
    }
  }
  if (!silent) console.log(chalk2.red("  enableScripts is not set in .yarnrc.yml (expected false)"));
  return false;
}
function fixEnableScripts(cwd) {
  const yarnrcPath = PATH2.join(cwd, ".yarnrc.yml");
  if (!existsSync3(yarnrcPath)) return true;
  const content = readFileSync2(yarnrcPath, "utf8");
  const lines = content.split("\n");
  let found = false;
  const newLines = lines.map((line) => {
    if (/^\s*enableScripts\s*:/.test(line)) {
      found = true;
      return "enableScripts: false";
    }
    return line;
  });
  if (!found) {
    let inserted = false;
    for (let i = 0; i < newLines.length; i++) {
      const trimmed = newLines[i].trim();
      if (trimmed && !trimmed.startsWith("#") && trimmed > "enableScripts:") {
        newLines.splice(i, 0, "enableScripts: false", "");
        inserted = true;
        break;
      }
    }
    if (!inserted) {
      const lastLine = newLines.at(-1);
      if (lastLine === "") {
        newLines.splice(-1, 0, "enableScripts: false", "");
      } else {
        newLines.push("", "enableScripts: false");
      }
    }
  }
  writeFileSync(yarnrcPath, newLines.join("\n"), "utf8");
  console.log(chalk2.green("  Fixed: enableScripts set to false"));
  return true;
}
function checkMinimumReleaseAge(cwd, config2, verbose, silent) {
  if (detectPackageManager() !== "pnpm") return true;
  const content = readPnpmWorkspaceYaml(cwd);
  if (!content) {
    if (!silent) console.log(chalk2.red("  No pnpm-workspace.yaml found"));
    return false;
  }
  const { minimumReleaseAge } = config2;
  for (const line of content.split("\n")) {
    const match = /^minimumReleaseAge\s*:\s*(\d+)/.exec(line.trim());
    if (match) {
      const value = Number.parseInt(match[1], 10);
      if (value >= minimumReleaseAge) {
        if (verbose) console.log(chalk2.green(`  minimumReleaseAge is ${value} (>= ${minimumReleaseAge})`));
        return true;
      }
      if (!silent) console.log(chalk2.red(`  minimumReleaseAge is ${value} (expected >= ${minimumReleaseAge})`));
      return false;
    }
  }
  if (!silent) console.log(chalk2.red(`  minimumReleaseAge is not set in pnpm-workspace.yaml (expected >= ${minimumReleaseAge})`));
  return false;
}
function fixMinimumReleaseAge(cwd, config2) {
  if (detectPackageManager() !== "pnpm") return true;
  const content = readPnpmWorkspaceYaml(cwd);
  if (!content) return false;
  const { minimumReleaseAge } = config2;
  const lines = content.split("\n");
  let found = false;
  const newLines = lines.map((line) => {
    if (/^minimumReleaseAge\s*:/.test(line)) {
      found = true;
      return `minimumReleaseAge: ${minimumReleaseAge}`;
    }
    return line;
  });
  if (!found) {
    const lastLine = newLines.at(-1);
    if (lastLine === "") {
      newLines.splice(-1, 0, `minimumReleaseAge: ${minimumReleaseAge}`);
    } else {
      newLines.push(`minimumReleaseAge: ${minimumReleaseAge}`);
    }
  }
  writePnpmWorkspaceYaml(cwd, newLines.join("\n"));
  console.log(chalk2.green(`  Fixed: minimumReleaseAge set to ${minimumReleaseAge}`));
  return true;
}
function checkMinimumReleaseAgeExclude(cwd, config2, verbose, silent) {
  if (detectPackageManager() !== "pnpm") return true;
  const content = readPnpmWorkspaceYaml(cwd);
  if (!content) {
    if (!silent) console.log(chalk2.red("  No pnpm-workspace.yaml found"));
    return false;
  }
  const excludes = parseYamlListSection(content, "minimumReleaseAgeExclude");
  const missing = config2.minimumReleaseAgeExclude.filter((scope) => !excludes.includes(scope));
  if (missing.length === 0) {
    if (verbose) console.log(chalk2.green("  minimumReleaseAgeExclude includes all required scopes"));
    return true;
  }
  if (!silent) console.log(chalk2.red(`  minimumReleaseAgeExclude is missing: ${missing.join(", ")}`));
  return false;
}
function fixMinimumReleaseAgeExclude(cwd, config2) {
  if (detectPackageManager() !== "pnpm") return true;
  const content = readPnpmWorkspaceYaml(cwd);
  if (!content) return false;
  const existingExcludes = parseYamlListSection(content, "minimumReleaseAgeExclude");
  const toAdd = config2.minimumReleaseAgeExclude.filter((scope) => !existingExcludes.includes(scope));
  if (toAdd.length === 0) return true;
  const lines = content.split("\n");
  const sectionIndex = lines.findIndex((line) => /^minimumReleaseAgeExclude\s*:/.test(line));
  if (sectionIndex === -1) {
    const newSection = ["minimumReleaseAgeExclude:", ...config2.minimumReleaseAgeExclude.map((s) => `  - ${s}`)];
    const lastLine = lines.at(-1);
    if (lastLine === "") {
      lines.splice(-1, 0, ...newSection);
    } else {
      lines.push(...newSection);
    }
  } else {
    let insertAt = sectionIndex + 1;
    while (insertAt < lines.length && /^\s+-/.test(lines[insertAt])) {
      insertAt++;
    }
    for (const scope of toAdd) {
      lines.splice(insertAt, 0, `  - ${scope}`);
      insertAt++;
    }
  }
  writePnpmWorkspaceYaml(cwd, lines.join("\n"));
  console.log(chalk2.green(`  Fixed: added ${toAdd.join(", ")} to minimumReleaseAgeExclude`));
  return true;
}
async function packmanLint({ fix, verbose } = {}) {
  const cwd = process.cwd();
  const pm = detectPackageManager();
  const rootConfig = await loadConfig();
  const packmanConfig = resolvePackmanConfig(rootConfig.commands ? rootConfig.commands.packman : void 0);
  let failures = 0;
  if (pm === "npm" || pm === "bun") {
    console.log(chalk2.green(`packman lint: no manager-specific checks are currently required for ${pm}`));
    return 0;
  }
  const enableScriptsPassed = checkEnableScripts(cwd, verbose, fix);
  if (!enableScriptsPassed) {
    if (fix) {
      if (!fixEnableScripts(cwd)) failures++;
    } else {
      failures++;
    }
  }
  const agePassed = checkMinimumReleaseAge(cwd, packmanConfig, verbose, fix);
  if (!agePassed) {
    if (fix) {
      if (!fixMinimumReleaseAge(cwd, packmanConfig)) failures++;
    } else {
      failures++;
    }
  }
  const excludePassed = checkMinimumReleaseAgeExclude(cwd, packmanConfig, verbose, fix);
  if (!excludePassed) {
    if (fix) {
      if (!fixMinimumReleaseAgeExclude(cwd, packmanConfig)) failures++;
    } else {
      failures++;
    }
  }
  if (failures > 0) {
    console.log(chalk2.red(`
packman lint: ${failures} check(s) failed`));
    if (!fix) {
      console.log(chalk2.yellow("Run with --fix to auto-fix issues"));
    }
  } else {
    console.log(chalk2.green("\npackman lint: all checks passed"));
  }
  return failures > 0 ? 1 : 0;
}
export {
  packmanLint
};
//# sourceMappingURL=lint.mjs.map
