// src/actions/packman/convertToYarn.ts
import {
  existsSync as existsSync3,
  readFileSync as readFileSync3,
  rmSync,
  writeFileSync as writeFileSync3
} from "fs";
import PATH2 from "path";
import chalk4 from "chalk";

// src/lib/packageManagerRuntime.ts
import { spawnSync } from "child_process";
import fs from "fs";
import chalk from "chalk";
var DISPLAY_NAMES = {
  bun: "Bun",
  npm: "npm",
  pnpm: "pnpm",
  yarn: "Yarn"
};
var MAC_INSTALL_COMMANDS = {
  bun: "brew install oven-sh/bun/bun",
  npm: "brew install node",
  pnpm: "brew install pnpm",
  yarn: "brew install yarn"
};
function currentPlatform() {
  if (process.platform === "darwin" || process.platform === "linux" || process.platform === "win32") {
    return process.platform;
  }
  return "unknown";
}
function askYesNo(question) {
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
    return false;
  }
  process.stdout.write(question);
  const buffer = Buffer.alloc(1024);
  const bytesRead = fs.readSync(process.stdin.fd, buffer, 0, buffer.length, null);
  const answer = buffer.toString("utf8", 0, bytesRead).trim().toLowerCase();
  return answer === "y" || answer === "yes";
}
function isCommandInstalled(command) {
  const result = spawnSync(command, ["--version"], {
    encoding: "utf8",
    shell: false,
    stdio: "ignore"
  });
  return !result.error && result.status === 0;
}
function isPackageManagerInstalled(pm) {
  return isCommandInstalled(pm);
}
function getPackageManagerInstallPlan(pm, platform = currentPlatform()) {
  const displayName = DISPLAY_NAMES[pm];
  if (platform === "darwin") {
    const command = MAC_INSTALL_COMMANDS[pm];
    return {
      command,
      manualInstructions: [
        `Install ${displayName} with: ${command}`
      ],
      packageManager: pm,
      platform,
      supported: true
    };
  }
  if (platform === "linux") {
    return {
      manualInstructions: [
        `Automatic installation for ${displayName} is not implemented on Linux yet.`,
        `Install ${displayName} manually and re-run the command.`
      ],
      packageManager: pm,
      platform,
      supported: false
    };
  }
  if (platform === "win32") {
    return {
      manualInstructions: [
        `Automatic installation for ${displayName} is not implemented on Windows yet.`,
        `Install ${displayName} manually and re-run the command.`
      ],
      packageManager: pm,
      platform,
      supported: false
    };
  }
  return {
    manualInstructions: [
      `Automatic installation for ${displayName} is not implemented on ${platform} yet.`,
      `Install ${displayName} manually and re-run the command.`
    ],
    packageManager: pm,
    platform,
    supported: false
  };
}
function printManualInstructions(plan, context) {
  console.error(chalk.yellow(`${DISPLAY_NAMES[plan.packageManager]} is required for "${context.operation}".`));
  for (const line of plan.manualInstructions) {
    console.error(chalk.gray(`  ${line}`));
  }
}
function installWithHomebrew(pm, cwd) {
  const command = MAC_INSTALL_COMMANDS[pm];
  const result = spawnSync("brew", command.replace("brew ", "").split(" "), {
    cwd,
    encoding: "utf8",
    shell: false,
    stdio: "inherit"
  });
  return result.status === 0;
}
function ensurePackageManagerInstalled(pm, context) {
  if (isPackageManagerInstalled(pm)) return true;
  const plan = getPackageManagerInstallPlan(pm, context.platform ?? currentPlatform());
  const displayName = DISPLAY_NAMES[pm];
  console.error(chalk.yellow(`${context.operation} requires ${displayName}, but it is not installed.`));
  if (!plan.supported) {
    printManualInstructions(plan, context);
    return false;
  }
  if (!isCommandInstalled("brew")) {
    console.error(chalk.yellow("Homebrew is not installed, so automatic installation is unavailable."));
    console.error(chalk.gray("  Install Homebrew from https://brew.sh and then run:"));
    console.error(chalk.gray(`  ${plan.command}`));
    return false;
  }
  const confirmed = askYesNo(chalk.cyan(`Install ${displayName} with Homebrew now? [y/N] `));
  if (!confirmed) {
    console.error(chalk.gray(`Skipping install. Run "${plan.command}" manually and then retry.`));
    return false;
  }
  console.error(chalk.cyan(`Installing ${displayName} via Homebrew...
`));
  if (!installWithHomebrew(pm, context.cwd)) {
    console.error(chalk.red(`Homebrew failed to install ${displayName}.`));
    console.error(chalk.gray(`Run "${plan.command}" manually and then retry.`));
    return false;
  }
  if (!isPackageManagerInstalled(pm)) {
    console.error(chalk.red(`${displayName} still does not appear to be installed after Homebrew completed.`));
    console.error(chalk.gray(`Run "${plan.command}" manually and then retry.`));
    return false;
  }
  console.error(chalk.green(`${displayName} installed successfully.`));
  return true;
}
function failureResult() {
  return {
    output: ["", ""],
    pid: 0,
    signal: null,
    status: 1,
    stderr: "",
    stdout: ""
  };
}
function spawnPackageManagerSync(pm, args, options) {
  if (!ensurePackageManagerInstalled(pm, options.context)) {
    return failureResult();
  }
  return spawnSync(pm, args, { encoding: "utf8", ...options });
}

// src/actions/packman/rewriteScripts.ts
function xyCommand(pm) {
  switch (pm) {
    case "bun": {
      return "bun run xy";
    }
    case "npm": {
      return "npm exec -- xy";
    }
    case "pnpm": {
      return "pnpm xy";
    }
    default: {
      return "yarn xy";
    }
  }
}
function rootRunCommand(pm, script, rest = "") {
  const suffix = rest.trim() ? ` ${rest.trim()}` : "";
  return `${pm} run ${script}${suffix}`;
}
function addCommand(pm) {
  switch (pm) {
    case "bun": {
      return "bun add";
    }
    case "npm": {
      return "npm install";
    }
    case "pnpm": {
      return "pnpm add";
    }
    default: {
      return "yarn add";
    }
  }
}
function removeCommand(pm) {
  switch (pm) {
    case "bun": {
      return "bun remove";
    }
    case "npm": {
      return "npm uninstall";
    }
    case "pnpm": {
      return "pnpm remove";
    }
    default: {
      return "yarn remove";
    }
  }
}
function installCommand(pm) {
  return `${pm} install`;
}
function outdatedCommand(pm) {
  return `${pm} outdated`;
}
function dedupeCommand(pm) {
  return pm === "npm" ? "npm dedupe" : `${pm} dedupe`;
}
function trimRest(rest) {
  if (!rest) return "";
  const normalized = rest.trim();
  return normalized ? ` ${normalized}` : "";
}
function workspaceRunCommand(pm, pkg, script, rest = "") {
  const suffix = trimRest(rest);
  switch (pm) {
    case "bun": {
      return `bun run --filter ${pkg} ${script}${suffix}`;
    }
    case "npm": {
      return `npm run ${script} --workspace=${pkg}${suffix}`;
    }
    case "pnpm": {
      return `pnpm --filter ${pkg} run ${script}${suffix}`;
    }
    default: {
      return `yarn workspace ${pkg} run ${script}${suffix}`;
    }
  }
}
function workspaceRunAllCommand(pm, script, rest = "") {
  const suffix = trimRest(rest);
  switch (pm) {
    case "bun": {
      return `bun run --workspaces --if-present ${script}${suffix}`;
    }
    case "npm": {
      return `npm run ${script} --workspaces --if-present${suffix}`;
    }
    case "pnpm": {
      return `pnpm -r run ${script}${suffix}`;
    }
    default: {
      return `yarn workspaces foreach -Apt run ${script}${suffix}`;
    }
  }
}
function normalizeWorkspaceCommands(script, target) {
  let result = script;
  result = result.replaceAll(/\byarn workspace (\S+) run (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\byarn workspace (\S+) (package-\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bpnpm --filter (\S+) run (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bpnpm --filter (\S+) (package-\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bnpm run (\S+) --workspace(?:=|\s+)(\S+)(?:\s+(.*))?$/g, (_, command, pkg, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bnpm --workspace(?:=|\s+)(\S+) run (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bnpm run (\S+) -w (\S+)(?:\s+(.*))?$/g, (_, command, pkg, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bbun run --filter (\S+) (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bbun --filter (\S+) run (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\byarn workspaces foreach\s+(?:[^\s]+\s+)*run (\S+)(?:\s+(.*))?$/g, (_, command, rest) => workspaceRunAllCommand(target, command, rest));
  result = result.replaceAll(/\bpnpm -r(?:\s+[^\s]+)* run (\S+)(?:\s+(.*))?$/g, (_, command, rest) => workspaceRunAllCommand(target, command, rest));
  result = result.replaceAll(/\bnpm run (\S+) --workspaces(?: --if-present)?(?:\s+(.*))?$/g, (_, command, rest) => workspaceRunAllCommand(target, command, rest));
  result = result.replaceAll(/\bbun run(?:\s+--[^\s]+)* --workspaces(?: --if-present)? (\S+)(?:\s+(.*))?$/g, (_, command, rest) => workspaceRunAllCommand(target, command, rest));
  return result;
}
function normalizeRootRunCommands(script, target) {
  let result = script;
  result = result.replaceAll(/\byarn run (\S+)(?:\s+(.*))?$/g, (_, command, rest) => rootRunCommand(target, command, rest));
  result = result.replaceAll(/\bpnpm run (\S+)(?:\s+(.*))?$/g, (_, command, rest) => rootRunCommand(target, command, rest));
  result = result.replaceAll(/\bnpm run (\S+)(?!\s+(?:--workspace(?:=|\s)|-w\s|--workspaces)\b)(?:\s+(.*))?$/g, (_, command, rest) => rootRunCommand(target, command, rest));
  result = result.replaceAll(/\bbun run (\S+)(?!\s+(?:--filter|--workspaces)\b)(?:\s+(.*))?$/g, (_, command, rest) => rootRunCommand(target, command, rest));
  return result;
}
function normalizeXyCommands(script, target) {
  return script.replaceAll(/\byarn xy\b/g, xyCommand(target)).replaceAll(/\bpnpm xy\b/g, xyCommand(target)).replaceAll(/\bnpm exec(?: --)? xy\b/g, xyCommand(target)).replaceAll(/\bnpx(?: --no-install)? xy\b/g, xyCommand(target)).replaceAll(/\bbun run xy\b/g, xyCommand(target)).replaceAll(/\bbun x xy\b/g, xyCommand(target));
}
function rewriteScript(script, target) {
  let result = normalizeWorkspaceCommands(script, target);
  result = normalizeRootRunCommands(result, target);
  result = normalizeXyCommands(result, target);
  result = result.replaceAll(/\byarn add\b/g, addCommand(target));
  result = result.replaceAll(/\bpnpm add\b/g, addCommand(target));
  result = result.replaceAll(/\bbun add\b/g, addCommand(target));
  result = result.replaceAll(/\byarn remove\b/g, removeCommand(target));
  result = result.replaceAll(/\bpnpm remove\b/g, removeCommand(target));
  result = result.replaceAll(/\bbun remove\b/g, removeCommand(target));
  result = result.replaceAll(/\bnpm uninstall\b/g, removeCommand(target));
  result = result.replaceAll(/\byarn install\b/g, installCommand(target));
  result = result.replaceAll(/\bpnpm install\b/g, installCommand(target));
  result = result.replaceAll(/\bbun install\b/g, installCommand(target));
  result = result.replaceAll(/\bnpm install\b/g, installCommand(target));
  result = result.replaceAll(/\byarn dedupe\b/g, dedupeCommand(target));
  result = result.replaceAll(/\bpnpm dedupe\b/g, dedupeCommand(target));
  result = result.replaceAll(/\bnpm dedupe\b/g, dedupeCommand(target));
  result = result.replaceAll(/\byarn outdated\b/g, outdatedCommand(target));
  result = result.replaceAll(/\bpnpm outdated\b/g, outdatedCommand(target));
  result = result.replaceAll(/\bbun outdated\b/g, outdatedCommand(target));
  result = result.replaceAll(/\bnpm outdated\b/g, outdatedCommand(target));
  return result;
}
function rewriteScriptsInPackageJson(pkg, target) {
  const scripts = pkg.scripts;
  if (!scripts) return pkg;
  const rewritten = {};
  for (const [name, script] of Object.entries(scripts)) {
    rewritten[name] = rewriteScript(script, target);
  }
  return { ...pkg, scripts: rewritten };
}

// src/actions/packman/rewriteSourceImports.ts
import {
  existsSync,
  readFileSync,
  writeFileSync
} from "fs";
import chalk2 from "chalk";
import { globSync } from "glob";
function targetImports(target) {
  const toolchainPackage = target === "pnpm" ? "@xylabs/ts-scripts-pnpm" : target === "yarn" ? "@xylabs/ts-scripts-yarn3" : "@xylabs/toolchain";
  return [
    ["@xylabs/toolchain", toolchainPackage],
    ["@xylabs/ts-scripts-yarn3", toolchainPackage],
    ["@xylabs/ts-scripts-pnpm", toolchainPackage]
  ];
}
var SOURCE_GLOBS = [
  "**/*.ts",
  "**/*.tsx",
  "**/*.mts",
  "**/*.cts",
  "**/*.js",
  "**/*.mjs"
];
var IGNORE_PATTERNS = [
  "**/node_modules/**",
  "**/dist/**",
  "**/build/**",
  "**/.yarn/**"
];
function rewriteSourceImports(cwd, target) {
  const swaps = targetImports(target);
  const files = globSync(SOURCE_GLOBS, {
    cwd,
    absolute: true,
    ignore: IGNORE_PATTERNS
  });
  let count = 0;
  for (const file of files) {
    if (!existsSync(file)) continue;
    const original = readFileSync(file, "utf8");
    let content = original;
    for (const [from, to] of swaps) {
      content = content.replaceAll(from, to);
    }
    if (content !== original) {
      writeFileSync(file, content, "utf8");
      count++;
    }
  }
  if (count > 0) {
    console.log(chalk2.green(`  Rewrote toolchain imports in ${count} source file(s)`));
  }
}

// src/actions/packman/swapTsScriptsDependency.ts
import {
  existsSync as existsSync2,
  readFileSync as readFileSync2,
  writeFileSync as writeFileSync2
} from "fs";
import PATH from "path";
import chalk3 from "chalk";
var managedPackages = [
  "@xylabs/toolchain",
  "@xylabs/ts-scripts-pnpm",
  "@xylabs/ts-scripts-yarn3"
];
function targetToolchainPackage(target) {
  switch (target) {
    case "pnpm": {
      return "@xylabs/ts-scripts-pnpm";
    }
    case "yarn": {
      return "@xylabs/ts-scripts-yarn3";
    }
    default: {
      return "@xylabs/toolchain";
    }
  }
}
function swapInPackageJson(pkgPath, target) {
  if (!existsSync2(pkgPath)) return false;
  const raw = readFileSync2(pkgPath, "utf8");
  const pkg = JSON.parse(raw);
  const targetPackage = targetToolchainPackage(target);
  let changed = false;
  for (const depField of ["dependencies", "devDependencies"]) {
    const deps = pkg[depField];
    if (!deps) continue;
    const existingVersion = managedPackages.map((name) => deps[name]).find(Boolean);
    if (!existingVersion) continue;
    for (const name of managedPackages) {
      if (deps[name]) {
        delete deps[name];
        changed = true;
      }
    }
    deps[targetPackage] = existingVersion;
  }
  if (changed) {
    writeFileSync2(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
  }
  return changed;
}
function swapTsScriptsDependency(cwd, workspacePackageJsonPaths, target) {
  let count = 0;
  if (swapInPackageJson(PATH.join(cwd, "package.json"), target)) {
    count++;
  }
  for (const pkgPath of workspacePackageJsonPaths) {
    const fullPath = PATH.resolve(cwd, pkgPath, "package.json");
    if (swapInPackageJson(fullPath, target)) {
      count++;
    }
  }
  if (count > 0) {
    console.log(chalk3.green(`  Set toolchain dependency to ${targetToolchainPackage(target)} in ${count} package(s)`));
  }
}

// src/actions/packman/convertToYarn.ts
var YARN_VERSION = "4.13.0";
var YARNRC_TEMPLATE = `compressionLevel: mixed

enableGlobalCache: true

enableInlineBuilds: true

nmHoistingLimits: none

nodeLinker: node-modules
`;
var YARN_GITIGNORE_ENTRIES = `
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
`;
function readPnpmWorkspacePatterns(cwd) {
  const wsPath = PATH2.join(cwd, "pnpm-workspace.yaml");
  if (!existsSync3(wsPath)) return [];
  const content = readFileSync3(wsPath, "utf8");
  const patterns = [];
  const lines = content.split("\n");
  let inPackages = false;
  for (const line of lines) {
    if (line.trim() === "packages:") {
      inPackages = true;
      continue;
    }
    if (inPackages && /^\s+-\s+/.test(line)) {
      const pattern = line.replace(/^\s+-\s+/, "").replaceAll(/['"]/g, "").trim();
      if (pattern) patterns.push(pattern);
    } else if (inPackages && !/^\s/.test(line) && line.trim()) {
      inPackages = false;
    }
  }
  return patterns;
}
function updateRootPackageJson(cwd, workspacePatterns) {
  const pkgPath = PATH2.join(cwd, "package.json");
  const pkg = JSON.parse(readFileSync3(pkgPath, "utf8"));
  pkg.workspaces = workspacePatterns;
  pkg.packageManager = `yarn@${YARN_VERSION}`;
  const updated = rewriteScriptsInPackageJson(pkg, "yarn");
  writeFileSync3(pkgPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
  console.log(chalk4.green("  Updated root package.json"));
}
function updateGitignore(cwd) {
  const gitignorePath = PATH2.join(cwd, ".gitignore");
  let content = existsSync3(gitignorePath) ? readFileSync3(gitignorePath, "utf8") : "";
  if (!content.includes(".yarn/*")) {
    content = content.trimEnd() + "\n" + YARN_GITIGNORE_ENTRIES;
  }
  writeFileSync3(gitignorePath, content, "utf8");
  console.log(chalk4.green("  Updated .gitignore"));
}
function deletePnpmArtifacts(cwd) {
  const lockfile = PATH2.join(cwd, "pnpm-lock.yaml");
  const workspaceYaml = PATH2.join(cwd, "pnpm-workspace.yaml");
  const npmrc = PATH2.join(cwd, ".npmrc");
  if (existsSync3(lockfile)) {
    rmSync(lockfile);
    console.log(chalk4.gray("  Deleted pnpm-lock.yaml"));
  }
  if (existsSync3(workspaceYaml)) {
    rmSync(workspaceYaml);
    console.log(chalk4.gray("  Deleted pnpm-workspace.yaml"));
  }
  if (existsSync3(npmrc)) {
    const content = readFileSync3(npmrc, "utf8");
    if (content.trim() === "" || content.includes("shamefully-hoist") || content.includes("node-linker")) {
      rmSync(npmrc);
      console.log(chalk4.gray("  Deleted .npmrc"));
    }
  }
}
function createYarnrc(cwd) {
  const yarnrcPath = PATH2.join(cwd, ".yarnrc.yml");
  if (existsSync3(yarnrcPath)) return;
  writeFileSync3(yarnrcPath, YARNRC_TEMPLATE, "utf8");
  console.log(chalk4.green("  Created .yarnrc.yml"));
}
function readWorkspacePatternsFromPackageJson(cwd) {
  const pkgPath = PATH2.join(cwd, "package.json");
  if (!existsSync3(pkgPath)) return [];
  const pkg = JSON.parse(readFileSync3(pkgPath, "utf8"));
  return pkg.workspaces ?? [];
}
function convertToYarn(cwd, workspacePackageJsonPaths) {
  console.log(chalk4.blue("\nConverting to yarn...\n"));
  const workspacePatterns = readPnpmWorkspacePatterns(cwd);
  if (workspacePatterns.length === 0) {
    const fromPkg = readWorkspacePatternsFromPackageJson(cwd);
    if (fromPkg.length > 0) {
      workspacePatterns.push(...fromPkg);
    } else {
      console.warn(chalk4.yellow("  No workspace patterns found"));
    }
  }
  updateRootPackageJson(cwd, workspacePatterns);
  for (const pkgPath of workspacePackageJsonPaths) {
    const fullPath = PATH2.resolve(cwd, pkgPath, "package.json");
    if (!existsSync3(fullPath)) continue;
    const pkg = JSON.parse(readFileSync3(fullPath, "utf8"));
    const updated = rewriteScriptsInPackageJson(pkg, "yarn");
    if (JSON.stringify(pkg) !== JSON.stringify(updated)) {
      writeFileSync3(fullPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
    }
  }
  console.log(chalk4.green(`  Rewrote scripts in ${workspacePackageJsonPaths.length} workspace package(s)`));
  updateGitignore(cwd);
  createYarnrc(cwd);
  swapTsScriptsDependency(cwd, workspacePackageJsonPaths, "yarn");
  rewriteSourceImports(cwd, "yarn");
  deletePnpmArtifacts(cwd);
  console.log(chalk4.blue("\nRunning yarn install..."));
  const install = spawnPackageManagerSync("yarn", ["install"], {
    context: { cwd, operation: "Convert repo to yarn and install dependencies" },
    cwd,
    encoding: "utf8",
    shell: true,
    stdio: "inherit"
  });
  if (install.status !== 0) {
    console.error(chalk4.red("yarn install failed"));
    return 1;
  }
  console.log(chalk4.blue("\nConversion complete.\n"));
  return 0;
}
export {
  convertToYarn
};
//# sourceMappingURL=convertToYarn.mjs.map