"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 __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 import_child_process = require("child_process");
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");
function resolveSessionName(sessionName) {
  if (sessionName)
    return sessionName;
  if (process.env.PLAYWRIGHT_CLI_SESSION)
    return process.env.PLAYWRIGHT_CLI_SESSION;
  return "default";
}
const globalOptions = [
  "browser",
  "config",
  "extension",
  "headed",
  "help",
  "persistent",
  "profile",
  "session",
  "version"
];
const booleanOptions = [
  "all",
  "help",
  "version"
];
async function program() {
  const clientInfo = (0, import_registry.createClientInfo)();
  const help = require("./help.json");
  const argv = process.argv.slice(2);
  const boolean = [...help.booleanOptions, ...booleanOptions];
  const args = require("minimist")(argv, { boolean, string: ["_"] });
  for (const [key, value] of Object.entries(args)) {
    if (key !== "_" && typeof value !== "boolean")
      args[key] = String(value);
  }
  for (let index = 0; index < args._.length; index++)
    args._[index] = String(args._[index]);
  for (const option of boolean) {
    if (!argv.includes(`--${option}`) && !argv.includes(`--no-${option}`))
      delete args[option];
    if (argv.some((arg) => arg.startsWith(`--${option}=`) || arg.startsWith(`--no-${option}=`))) {
      console.error(`boolean option '--${option}' should not be passed with '=value', use '--${option}' or '--no-${option}' instead`);
      process.exit(1);
    }
  }
  if (args.s) {
    args.session = args.s;
    delete args.s;
  }
  const commandName = args._?.[0];
  if (args.version || args.v) {
    console.log(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 = 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(clientInfo, entry.config).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(clientInfo, entry.config).deleteData();
      return;
    }
    case "kill-all": {
      await killAllDaemons();
      return;
    }
    case "open": {
      const entry = registry.entry(clientInfo, sessionName);
      if (entry)
        await new import_session.Session(clientInfo, entry.config).stop(true);
      const session2 = new import_session.Session(clientInfo, sessionConfigFromArgs(clientInfo, sessionName, args));
      if (await session2.canConnect())
        await session2.stop(true);
      for (const globalOption of globalOptions)
        delete args[globalOption];
      const result = await session2.run(args);
      console.log(result.text);
      return;
    }
    case "close":
      const closeEntry = registry.entry(clientInfo, sessionName);
      const session = closeEntry ? new import_session.Session(clientInfo, closeEntry.config) : 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 "show": {
      const daemonScript = import_path.default.join(__dirname, "devtoolsApp.js");
      const child = (0, import_child_process.spawn)(process.execPath, [daemonScript], {
        detached: true,
        stdio: "ignore"
      });
      child.unref();
      return;
    }
    default: {
      const defaultEntry = registry.entry(clientInfo, sessionName);
      if (!defaultEntry) {
        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);
      }
      for (const globalOption of globalOptions)
        delete args[globalOption];
      const result = await new import_session.Session(clientInfo, defaultEntry.config).run(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)}\`.`);
  }
  if (!args.config)
    await ensureConfiguredBrowserInstalled();
}
async function ensureConfiguredBrowserInstalled() {
  if (import_fs.default.existsSync(defaultConfigFile())) {
    const { registry } = await import("playwright-core/lib/server/registry/index");
    const config = JSON.parse(await import_fs.default.promises.readFile(defaultConfigFile(), "utf-8"));
    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 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 daemonSocketPath(clientInfo, sessionName) {
  const socketName = `${sessionName}.sock`;
  if (import_os.default.platform() === "win32")
    return `\\\\.\\pipe\\${clientInfo.workspaceDirHash}-${socketName}`;
  const socketsDir = process.env.PLAYWRIGHT_DAEMON_SOCKETS_DIR || import_path.default.join(import_os.default.tmpdir(), "playwright-cli");
  return import_path.default.join(socketsDir, clientInfo.workspaceDirHash, socketName);
}
function defaultConfigFile() {
  return import_path.default.resolve(".playwright", "cli.config.json");
}
function sessionConfigFromArgs(clientInfo, sessionName, args) {
  let config = args.config ? import_path.default.resolve(args.config) : void 0;
  try {
    if (!config && import_fs.default.existsSync(defaultConfigFile()))
      config = defaultConfigFile();
  } catch {
  }
  if (!args.persistent && args.profile)
    args.persistent = true;
  return {
    name: sessionName,
    version: clientInfo.version,
    timestamp: 0,
    socketPath: daemonSocketPath(clientInfo, sessionName),
    cli: {
      headed: args.headed,
      extension: args.extension,
      browser: args.browser,
      persistent: args.persistent,
      profile: args.profile,
      config
    },
    userDataDirPrefix: import_path.default.resolve(clientInfo.daemonProfilesDir, `ud-${sessionName}`),
    workspaceDir: clientInfo.workspaceDir
  };
}
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 '*-server*' -and $_.CommandLine -like '*--daemon-session*' } | 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("-server") && line.includes("--daemon-session")) {
          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();
    if (entries.size === 0) {
      console.log("No browsers found.");
      return;
    }
    for (const [workspace, list] of entries) {
      if (!list.length)
        continue;
      console.log(`${workspace}:`);
      await gcAndPrintSessions(list.map((entry) => new import_session.Session(clientInfo, entry.config)));
    }
  } else {
    console.log("### Browsers");
    const entries = registry.entries(clientInfo);
    await gcAndPrintSessions(entries.map((entry) => new import_session.Session(clientInfo, entry.config)));
  }
}
async function gcAndPrintSessions(sessions) {
  const running = [];
  const stopped = [];
  for (const session of sessions) {
    const canConnect = await session.canConnect();
    if (canConnect) {
      running.push(session);
    } else {
      if (session.config.cli.persistent)
        stopped.push(session);
      else
        await session.deleteSessionConfig();
    }
  }
  for (const session of running)
    console.log(await renderSessionStatus(session));
  for (const session of stopped)
    console.log(await renderSessionStatus(session));
  if (running.length === 0 && stopped.length === 0)
    console.log("  (no browsers)");
}
async function renderSessionStatus(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())
    text.push(`  - version: v${config.version} [incompatible please re-open]`);
  if (config.resolvedConfig)
    text.push(...(0, import_session.renderResolvedConfig)(config.resolvedConfig));
  return text.join("\n");
}
program().catch((e) => {
  console.error(e.message);
  process.exit(1);
});
