#!/usr/bin/env node
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
  if (typeof require !== "undefined") return require.apply(this, arguments);
  throw Error('Dynamic require of "' + x + '" is not supported');
});

// scripts/preuninstall.ts
import { existsSync, readFileSync, writeFileSync, appendFileSync, copyFileSync, renameSync, unlinkSync } from "fs";
import { homedir, tmpdir } from "os";
import { join } from "path";
var LOG_FILE = join(tmpdir(), "opencode-orchestrator.log");
function log(message, data) {
  try {
    const timestamp = (/* @__PURE__ */ new Date()).toISOString();
    const entry = `[${timestamp}] [preuninstall] ${message} ${data ? JSON.stringify(data) : ""}
`;
    appendFileSync(LOG_FILE, entry);
  } catch {
  }
}
function formatError(err, context) {
  if (err instanceof Error) {
    const nodeErr = err;
    if (nodeErr.code === "EACCES" || nodeErr.code === "EPERM") {
      return `Permission denied: Cannot ${context}. Try running as administrator.`;
    }
    if (nodeErr.code === "ENOENT") {
      return `File not found while trying to ${context}.`;
    }
    if (err instanceof SyntaxError) {
      return `JSON syntax error while trying to ${context}: ${err.message}.`;
    }
    if (nodeErr.code === "EIO") {
      return `File lock error: Cannot ${context}. Please close OpenCode and try again.`;
    }
    if (nodeErr.code === "ENOSPC") {
      return `Disk full: Cannot ${context}. Free up disk space and try again.`;
    }
    if (nodeErr.code === "EROFS") {
      return `Read-only filesystem: Cannot ${context}.`;
    }
    return `Failed to ${context}: ${err.message}`;
  }
  return `Failed to ${context}: ${String(err)}`;
}
var PLUGIN_NAME = "opencode-orchestrator";
function getConfigPaths() {
  const paths = [];
  if (process.env.XDG_CONFIG_HOME) {
    paths.push(join(process.env.XDG_CONFIG_HOME, "opencode"));
  }
  if (process.platform === "win32") {
    const appDataPath = process.env.APPDATA || join(homedir(), "AppData", "Roaming");
    paths.push(join(appDataPath, "opencode"));
    const dotConfigPath = join(homedir(), ".config", "opencode");
    if (!paths.includes(dotConfigPath)) {
      paths.push(dotConfigPath);
    }
  } else {
    paths.push(join(homedir(), ".config", "opencode"));
  }
  return paths;
}
function validateConfig(config) {
  try {
    if (typeof config !== "object" || config === null) {
      return false;
    }
    if (config.plugin !== void 0 && !Array.isArray(config.plugin)) {
      return false;
    }
    if (config.plugin) {
      for (const p of config.plugin) {
        if (typeof p !== "string") {
          return false;
        }
      }
    }
    return true;
  } catch {
    return false;
  }
}
function createBackup(configFile) {
  try {
    if (!existsSync(configFile)) {
      return null;
    }
    const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
    const backupFile = `${configFile}.backup.${timestamp}`;
    copyFileSync(configFile, backupFile);
    log("Backup created", { backupFile });
    return backupFile;
  } catch (error) {
    log("Failed to create backup", { error: String(error) });
    return null;
  }
}
function atomicWriteJSON(filePath, data) {
  const tempFile = `${filePath}.tmp.${Date.now()}`;
  try {
    writeFileSync(tempFile, JSON.stringify(data, null, 2) + "\n", { mode: 420 });
    renameSync(tempFile, filePath);
    log("Atomic write successful", { filePath });
  } catch (error) {
    try {
      if (existsSync(tempFile)) {
        unlinkSync(tempFile);
      }
    } catch {
    }
    throw error;
  }
}
function removeFromConfig(configDir) {
  const configFile = join(configDir, "opencode.json");
  let backupFile = null;
  try {
    if (!existsSync(configFile)) {
      log("Config file does not exist", { configFile });
      return { success: false, backupFile: null };
    }
    backupFile = createBackup(configFile);
    const content = readFileSync(configFile, "utf-8").trim();
    if (!content) {
      log("Empty config file", { configFile });
      return { success: false, backupFile };
    }
    let config;
    try {
      config = JSON.parse(content);
    } catch (error) {
      log("Failed to parse config, skipping", { error: String(error), configFile });
      console.log(`\u26A0\uFE0F  Corrupted config detected. Backup saved: ${backupFile}`);
      return { success: false, backupFile };
    }
    if (!validateConfig(config)) {
      log("Invalid config structure, skipping", { config, configFile });
      return { success: false, backupFile };
    }
    if (!config.plugin || !Array.isArray(config.plugin)) {
      log("No plugin array found", { configFile });
      return { success: false, backupFile };
    }
    const originalLength = config.plugin.length;
    const originalPlugins = [...config.plugin];
    config.plugin = config.plugin.filter((p) => {
      if (typeof p !== "string") return true;
      return p !== PLUGIN_NAME && !p.includes(PLUGIN_NAME);
    });
    if (config.plugin.length === originalLength) {
      log("Plugin not found in config", { configFile });
      return { success: false, backupFile };
    }
    const removedCount = originalLength - config.plugin.length;
    log("Removing plugin from config", {
      plugin: PLUGIN_NAME,
      removedCount,
      originalPlugins,
      newPlugins: config.plugin,
      configFile
    });
    atomicWriteJSON(configFile, config);
    try {
      const verifyContent = readFileSync(configFile, "utf-8");
      const verifyConfig = JSON.parse(verifyContent);
      const stillHasPlugin = verifyConfig.plugin?.some(
        (p) => typeof p === "string" && (p === PLUGIN_NAME || p.includes(PLUGIN_NAME))
      );
      if (stillHasPlugin) {
        throw new Error("Verification failed: plugin still present after removal");
      }
    } catch (verifyError) {
      log("Write verification failed, rolling back", { error: String(verifyError) });
      if (backupFile && existsSync(backupFile)) {
        copyFileSync(backupFile, configFile);
        console.log(`\u26A0\uFE0F  Write verification failed. Restored from backup.`);
      }
      throw verifyError;
    }
    log("Plugin removed successfully", { configFile, removedCount });
    return { success: true, backupFile };
  } catch (error) {
    log("Removal failed", { error: String(error), configFile });
    if (backupFile && existsSync(backupFile)) {
      try {
        copyFileSync(backupFile, configFile);
        log("Rolled back to backup", { backupFile });
        console.log(`\u26A0\uFE0F  Removal failed. Restored from backup: ${backupFile}`);
      } catch (rollbackError) {
        log("Rollback failed", { error: String(rollbackError) });
      }
    }
    return { success: false, backupFile };
  }
}
function cleanupOldBackups(configFile) {
  try {
    const configDir = join(configFile, "..");
    const files = __require("fs").readdirSync(configDir);
    const backupFiles = files.filter((f) => f.startsWith("opencode.json.backup.")).sort().reverse();
    for (let i = 5; i < backupFiles.length; i++) {
      const backupPath = join(configDir, backupFiles[i]);
      try {
        unlinkSync(backupPath);
        log("Deleted old backup", { file: backupFiles[i] });
      } catch {
      }
    }
  } catch {
  }
}
try {
  console.log("\u{1F9F9} OpenCode Orchestrator - Uninstalling...");
  log("Uninstallation started", { platform: process.platform, node: process.version });
  const configPaths = getConfigPaths();
  log("Config paths to check", configPaths);
  let removed = false;
  let backupCreated = null;
  for (const configDir of configPaths) {
    const configFile = join(configDir, "opencode.json");
    const result = removeFromConfig(configDir);
    if (result.success) {
      console.log(`\u2705 Plugin removed: ${configFile}`);
      if (result.backupFile) {
        console.log(`   Backup created: ${result.backupFile}`);
        backupCreated = result.backupFile;
      }
      removed = true;
      cleanupOldBackups(configFile);
    } else if (result.backupFile) {
      backupCreated = result.backupFile;
    }
  }
  if (!removed) {
    console.log("\u2705 Plugin was not registered. Nothing to clean up.");
    log("Plugin was not registered");
  }
  console.log("");
  log("Uninstallation completed", { removed, backupCreated });
} catch (error) {
  log("Uninstallation error", { error: String(error) });
  console.error("\u274C " + formatError(error, "clean up config"));
  console.log(`   Check logs: ${LOG_FILE}`);
  process.exit(0);
}
