import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, unlinkSync, lstatSync, renameSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { execSync } from "node:child_process";
function getPackageRoot() {
  const here = dirname(fileURLToPath(import.meta.url));
  return join(here, "..", "..", "..");
}
function getVersion() {
  try {
    const raw = readFileSync(join(getPackageRoot(), "package.json"), "utf-8");
    const pkg = JSON.parse(raw);
    return pkg.version ?? "0.0.0";
  } catch {
    return "0.0.0";
  }
}
function readAsset(relPath) {
  const full = join(getPackageRoot(), "assets", relPath);
  return readFileSync(full, "utf-8").replace(/\{version\}/g, getVersion());
}
function readSkillDir(name) {
  const dir = join(getPackageRoot(), "assets", "skills", name);
  const result = {};
  const mainPath = join(dir, "SKILL.md");
  if (existsSync(mainPath)) {
    result["SKILL.md"] = readFileSync(mainPath, "utf-8");
  }
  const rulesDir = join(dir, "rules");
  if (existsSync(rulesDir)) {
    for (const file of readdirSync(rulesDir)) {
      if (file.endsWith(".md")) {
        result[`rules/${file}`] = readFileSync(join(rulesDir, file), "utf-8");
      }
    }
  }
  return result;
}
function rotateBackup(bakPath) {
  if (!existsSync(bakPath)) return;
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
  let target = `${bakPath}.${ts}`;
  let suffix = 0;
  while (existsSync(target)) {
    suffix += 1;
    target = `${bakPath}.${ts}-${suffix}`;
  }
  try {
    renameSync(bakPath, target);
  } catch {
  }
}
function mergeBlock(filePath, block) {
  mkdirSync(dirname(filePath), { recursive: true });
  const START = "<!-- wigolo:start";
  const END = "<!-- wigolo:end -->";
  if (!existsSync(filePath)) {
    writeFileSync(filePath, block.trimEnd() + "\n", "utf-8");
    return;
  }
  const content = readFileSync(filePath, "utf-8");
  const startIdx = content.indexOf(START);
  const endIdx = content.indexOf(END);
  const hasStart = startIdx !== -1;
  const hasEnd = endIdx !== -1;
  if (hasStart && hasEnd) {
    const before = content.slice(0, startIdx).trimEnd();
    const after = content.slice(endIdx + END.length).trimStart();
    const parts = [before, block.trimEnd(), after].filter(Boolean);
    writeFileSync(filePath, parts.join("\n\n") + "\n", "utf-8");
    return;
  }
  if (hasStart !== hasEnd) {
    rotateBackup(filePath + ".wigolo-bak");
    writeFileSync(filePath + ".wigolo-bak", content, "utf-8");
    let salvaged = content;
    if (hasStart) {
      const lineEnd = content.indexOf("\n", startIdx);
      salvaged = (content.slice(0, startIdx).trimEnd() + (lineEnd === -1 ? "" : "\n" + content.slice(lineEnd + 1))).trimEnd();
    } else {
      const lineStart = content.lastIndexOf("\n", endIdx);
      const lineEnd = content.indexOf("\n", endIdx);
      const head = lineStart === -1 ? "" : content.slice(0, lineStart);
      const tail = lineEnd === -1 ? "" : content.slice(lineEnd + 1);
      salvaged = (head + (head && tail ? "\n" : "") + tail).trimEnd();
    }
    const out = salvaged ? salvaged + "\n\n" + block.trimEnd() + "\n" : block.trimEnd() + "\n";
    writeFileSync(filePath, out, "utf-8");
    return;
  }
  const trimmed = content.trimEnd();
  writeFileSync(filePath, trimmed + "\n\n" + block.trimEnd() + "\n", "utf-8");
}
function removeBlock(filePath) {
  if (!existsSync(filePath)) return false;
  const START = "<!-- wigolo:start";
  const END = "<!-- wigolo:end -->";
  const content = readFileSync(filePath, "utf-8");
  const startIdx = content.indexOf(START);
  const endIdx = content.indexOf(END);
  if (startIdx === -1 || endIdx === -1) return false;
  const before = content.slice(0, startIdx).trimEnd();
  const after = content.slice(endIdx + END.length).trimStart();
  const parts = [before, after].filter(Boolean);
  const newContent = parts.join("\n\n");
  if (!newContent) {
    let isSymlink = false;
    try {
      isSymlink = lstatSync(filePath).isSymbolicLink();
    } catch {
      isSymlink = false;
    }
    if (!isSymlink) {
      try {
        unlinkSync(filePath);
        return true;
      } catch {
      }
    }
    writeFileSync(filePath, "", "utf-8");
    return true;
  }
  writeFileSync(filePath, newContent + "\n", "utf-8");
  return true;
}
function mergeMcpJson(configPath, entry, keyPath) {
  mkdirSync(dirname(configPath), { recursive: true });
  let root = {};
  if (existsSync(configPath)) {
    try {
      root = JSON.parse(readFileSync(configPath, "utf-8"));
    } catch {
      root = {};
    }
  }
  let obj = root;
  for (let i = 0; i < keyPath.length - 1; i++) {
    const key = keyPath[i];
    if (typeof obj[key] !== "object" || obj[key] === null) {
      obj[key] = {};
    }
    obj = obj[key];
  }
  obj[keyPath[keyPath.length - 1]] = entry;
  writeFileSync(configPath, JSON.stringify(root, null, 2) + "\n", "utf-8");
}
function removeMcpJson(configPath, keyPath) {
  if (!existsSync(configPath)) return;
  let root;
  try {
    root = JSON.parse(readFileSync(configPath, "utf-8"));
  } catch {
    return;
  }
  let obj = root;
  for (let i = 0; i < keyPath.length - 1; i++) {
    const key = keyPath[i];
    if (typeof obj[key] !== "object" || obj[key] === null) return;
    obj = obj[key];
  }
  delete obj[keyPath[keyPath.length - 1]];
  writeFileSync(configPath, JSON.stringify(root, null, 2) + "\n", "utf-8");
}
function detectFirecrawlSkills(skillsBase) {
  if (!existsSync(skillsBase)) return [];
  let entries;
  try {
    entries = readdirSync(skillsBase);
  } catch {
    return [];
  }
  return entries.filter((name) => name === "firecrawl" || name.startsWith("firecrawl-")).sort();
}
function getMcpCommand() {
  try {
    const path = execSync("which wigolo", {
      encoding: "utf-8",
      stdio: ["pipe", "pipe", "pipe"]
    }).trim();
    if (path) {
      return { command: "wigolo", args: [] };
    }
  } catch {
  }
  return { command: "npx", args: ["-y", "@staticn0va/wigolo"] };
}
export {
  detectFirecrawlSkills,
  getMcpCommand,
  getVersion,
  mergeBlock,
  mergeMcpJson,
  readAsset,
  readSkillDir,
  removeBlock,
  removeMcpJson
};
//# sourceMappingURL=utils.js.map