"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var program_exports = {};
__export(program_exports, {
  calculateSha1: () => calculateSha1,
  program: () => program
});
module.exports = __toCommonJS(program_exports);
var import_child_process = require("child_process");
var import_crypto = __toESM(require("crypto"));
var import_fs = __toESM(require("fs"));
var import_os = __toESM(require("os"));
var import_path = __toESM(require("path"));
var import_registry = require("./registry");
var import_session = require("./session");
var import_serverRegistry = require("../../serverRegistry");
var import_minimist = require("./minimist");
const globalOptions = [
  "attach",
  "browser",
  "config",
  "extension",
  "headed",
  "help",
  "persistent",
  "profile",
  "session",
  "version"
];
const booleanOptions = [
  "all",
  "help",
  "version"
];
async function program(options) {
  const clientInfo = (0, import_registry.createClientInfo)();
  const help = require("./help.json");
  const argv = process.argv.slice(2);
  const boolean = [...help.booleanOptions, ...booleanOptions];
  const args = (0, import_minimist.minimist)(argv, { boolean, string: ["_"] });
  if (args.s) {
    args.session = args.s;
    delete args.s;
  }
  const commandName = args._?.[0];
  if (args.version || args.v) {
    console.log(options?.embedderVersion ?? clientInfo.version);
    process.exit(0);
  }
  const command = commandName && help.commands[commandName];
  if (args.help || args.h) {
    if (command) {
      console.log(command);
    } else {
      console.log("playwright-cli - run playwright mcp commands from terminal\n");
      console.log(help.global);
    }
    process.exit(0);
  }
  if (!command) {
    console.error(`Unknown command: ${commandName}
`);
    console.log(help.global);
    process.exit(1);
  }
  const registry = await import_registry.Registry.load();
  const sessionName = (0, import_registry.resolveSessionName)(args.session);
  switch (commandName) {
    case "list": {
      await listSessions(registry, clientInfo, !!args.all);
      return;
    }
    case "close-all": {
      const entries = registry.entries(clientInfo);
      for (const entry of entries)
        await new import_session.Session(entry).stop(true);
      return;
    }
    case "delete-data": {
      const entry = registry.entry(clientInfo, sessionName);
      if (!entry) {
        console.log(`No user data found for browser '${sessionName}'.`);
        return;
      }
      await new import_session.Session(entry).deleteData();
      return;
    }
    case "kill-all": {
      await killAllDaemons();
      return;
    }
    case "open": {
      await startSession(sessionName, registry, clientInfo, args);
      return;
    }
    case "attach": {
      const attachTarget = args._[1];
      const attachSessionName = (0, import_registry.explicitSessionName)(args.session) ?? attachTarget;
      args.attach = attachTarget;
      args.session = attachSessionName;
      await startSession(attachSessionName, registry, clientInfo, args);
      return;
    }
    case "close":
      const closeEntry = registry.entry(clientInfo, sessionName);
      const session = closeEntry ? new import_session.Session(closeEntry) : void 0;
      if (!session || !await session.canConnect()) {
        console.log(`Browser '${sessionName}' is not open.`);
        return;
      }
      await session.stop();
      return;
    case "install":
      await install(args);
      return;
    case "install-browser":
      await installBrowser();
      return;
    case "show": {
      const daemonScript = require.resolve("../dashboard/dashboardApp.js");
      const child = (0, import_child_process.spawn)(process.execPath, [daemonScript], {
        detached: true,
        stdio: "ignore"
      });
      child.unref();
      return;
    }
    default: {
      const entry = registry.entry(clientInfo, sessionName);
      if (!entry) {
        console.log(`The browser '${sessionName}' is not open, please run open first`);
        console.log("");
        console.log(`  playwright-cli${sessionName !== "default" ? ` -s=${sessionName}` : ""} open [params]`);
        process.exit(1);
      }
      await runInSession(entry, clientInfo, args);
    }
  }
}
async function startSession(sessionName, registry, clientInfo, args) {
  const entry = registry.entry(clientInfo, sessionName);
  if (entry)
    await new import_session.Session(entry).stop(true);
  await import_session.Session.startDaemon(clientInfo, args);
  const newEntry = await registry.loadEntry(clientInfo, sessionName);
  await runInSession(newEntry, clientInfo, args);
}
async function runInSession(entry, clientInfo, args) {
  for (const globalOption of globalOptions)
    delete args[globalOption];
  const session = new import_session.Session(entry);
  const result = await session.run(clientInfo, args);
  console.log(result.text);
}
async function install(args) {
  const cwd = process.cwd();
  const playwrightDir = import_path.default.join(cwd, ".playwright");
  await import_fs.default.promises.mkdir(playwrightDir, { recursive: true });
  console.log(`\u2705 Workspace initialized at \`${cwd}\`.`);
  if (args.skills) {
    const skillSourceDir = import_path.default.join(__dirname, "skill");
    const skillDestDir = import_path.default.join(cwd, ".claude", "skills", "playwright-cli");
    if (!import_fs.default.existsSync(skillSourceDir)) {
      console.error("\u274C Skills source directory not found:", skillSourceDir);
      process.exit(1);
    }
    await import_fs.default.promises.cp(skillSourceDir, skillDestDir, { recursive: true });
    console.log(`\u2705 Skills installed to \`${import_path.default.relative(cwd, skillDestDir)}\`.`);
  }
  await ensureConfiguredBrowserInstalled();
}
async function ensureConfiguredBrowserInstalled() {
  if (import_fs.default.existsSync(defaultConfigFile())) {
    const { registry } = await import("playwright-core/lib/server/registry/index");
    const data = await import_fs.default.promises.readFile(defaultConfigFile(), "utf-8");
    const config = JSON.parse(data.charCodeAt(0) === 65279 ? data.slice(1) : data);
    const browserName = config.browser?.browserName ?? "chromium";
    const channel = config.browser?.launchOptions?.channel;
    if (!channel || channel.startsWith("chromium")) {
      const executable = registry.findExecutable(channel ?? browserName);
      if (executable && !import_fs.default.existsSync(executable?.executablePath()))
        await registry.install([executable]);
    }
  } else {
    const channel = await findOrInstallDefaultBrowser();
    if (channel !== "chrome")
      await createDefaultConfig(channel);
  }
}
async function installBrowser() {
  const { program: program2 } = require("../../cli/program");
  const argv = process.argv.map((arg) => arg === "install-browser" ? "install" : arg);
  program2.parse(argv);
}
async function createDefaultConfig(channel) {
  const config = {
    browser: {
      browserName: "chromium",
      launchOptions: {
        channel
      }
    }
  };
  await import_fs.default.promises.writeFile(defaultConfigFile(), JSON.stringify(config, null, 2));
  console.log(`\u2705 Created default config for ${channel} at ${import_path.default.relative(process.cwd(), defaultConfigFile())}.`);
}
async function findOrInstallDefaultBrowser() {
  const { registry } = await import("playwright-core/lib/server/registry/index");
  const channels = ["chrome", "msedge"];
  for (const channel of channels) {
    const executable = registry.findExecutable(channel);
    if (!executable?.executablePath())
      continue;
    console.log(`\u2705 Found ${channel}, will use it as the default browser.`);
    return channel;
  }
  const chromiumExecutable = registry.findExecutable("chromium");
  if (!import_fs.default.existsSync(chromiumExecutable?.executablePath()))
    await registry.install([chromiumExecutable]);
  return "chromium";
}
function defaultConfigFile() {
  return import_path.default.resolve(".playwright", "cli.config.json");
}
async function killAllDaemons() {
  const platform = import_os.default.platform();
  let killed = 0;
  try {
    if (platform === "win32") {
      const result = (0, import_child_process.execSync)(
        `powershell -NoProfile -NonInteractive -Command "Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like '*run-mcp-server*' -or $_.CommandLine -like '*run-cli-server*' -or $_.CommandLine -like '*cli-daemon*' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue; $_.ProcessId }"`,
        { encoding: "utf-8" }
      );
      const pids = result.split("\n").map((line) => line.trim()).filter((line) => /^\d+$/.test(line));
      for (const pid of pids)
        console.log(`Killed daemon process ${pid}`);
      killed = pids.length;
    } else {
      const result = (0, import_child_process.execSync)("ps aux", { encoding: "utf-8" });
      const lines = result.split("\n");
      for (const line of lines) {
        if (line.includes("run-mcp-server") || line.includes("run-cli-server") || line.includes("cli-daemon")) {
          const parts = line.trim().split(/\s+/);
          const pid = parts[1];
          if (pid && /^\d+$/.test(pid)) {
            try {
              process.kill(parseInt(pid, 10), "SIGKILL");
              console.log(`Killed daemon process ${pid}`);
              killed++;
            } catch {
            }
          }
        }
      }
    }
  } catch (e) {
  }
  if (killed === 0)
    console.log("No daemon processes found.");
  else if (killed > 0)
    console.log(`Killed ${killed} daemon process${killed === 1 ? "" : "es"}.`);
}
async function listSessions(registry, clientInfo, all) {
  if (all) {
    const entries = registry.entryMap();
    const serverEntries = await import_serverRegistry.serverRegistry.list();
    if (entries.size === 0 && serverEntries.size === 0) {
      console.log("No browsers found.");
      return;
    }
    const runningSessions = /* @__PURE__ */ new Set();
    if (entries.size)
      console.log("### Browsers");
    for (const [workspace, list] of entries)
      await gcAndPrintSessions(clientInfo, list.map((entry) => new import_session.Session(entry)), `${import_path.default.relative(process.cwd(), workspace) || "/"}:`, runningSessions);
    const filteredServerEntries = /* @__PURE__ */ new Map();
    for (const [workspace, list] of serverEntries) {
      const unattached = list.filter((d) => !runningSessions.has(d.title));
      if (unattached.length)
        filteredServerEntries.set(workspace, unattached);
    }
    if (filteredServerEntries.size) {
      if (entries.size)
        console.log("");
      console.log("### Browser servers available for attach");
    }
    for (const [workspace, list] of filteredServerEntries)
      await gcAndPrintBrowserSessions(workspace, list);
  } else {
    console.log("### Browsers");
    const entries = registry.entries(clientInfo);
    await gcAndPrintSessions(clientInfo, entries.map((entry) => new import_session.Session(entry)));
  }
}
async function gcAndPrintSessions(clientInfo, sessions, header, runningSessions) {
  const running = [];
  const stopped = [];
  for (const session of sessions) {
    const canConnect = await session.canConnect();
    if (canConnect) {
      running.push(session);
      runningSessions?.add(session.name);
    } else {
      if (session.config.cli.persistent)
        stopped.push(session);
      else
        await session.deleteSessionConfig();
    }
  }
  if (header && (running.length || stopped.length))
    console.log(header);
  for (const session of running)
    console.log(await renderSessionStatus(clientInfo, session));
  for (const session of stopped)
    console.log(await renderSessionStatus(clientInfo, session));
  if (running.length === 0 && stopped.length === 0)
    console.log("  (no browsers)");
}
async function gcAndPrintBrowserSessions(workspace, list) {
  if (!list.length)
    return;
  if (workspace)
    console.log(`${import_path.default.relative(process.cwd(), workspace) || "/"}:`);
  for (const descriptor of list) {
    const text = [];
    text.push(`- browser "${descriptor.title}":`);
    text.push(`  - browser: ${descriptor.browser.browserName}`);
    text.push(`  - version: v${descriptor.playwrightVersion}`);
    text.push(`  - run \`playwright-cli attach "${descriptor.title}"\` to attach`);
    console.log(text.join("\n"));
  }
  if (!list.length)
    console.log("  (no browsers)");
}
async function renderSessionStatus(clientInfo, session) {
  const text = [];
  const config = session.config;
  const canConnect = await session.canConnect();
  text.push(`- ${session.name}:`);
  text.push(`  - status: ${canConnect ? "open" : "closed"}`);
  if (canConnect && !session.isCompatible(clientInfo))
    text.push(`  - version: v${config.version} [incompatible please re-open]`);
  if (config.browser)
    text.push(...(0, import_session.renderResolvedConfig)(config));
  return text.join("\n");
}
function calculateSha1(buffer) {
  const hash = import_crypto.default.createHash("sha1");
  hash.update(buffer);
  return hash.digest("hex");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  calculateSha1,
  program
});
