// Post-install wiring for the imessage module. Runs after the module is
// copied into <installPath>/services/imessage/ and `npm install` completes.
//
// Responsibilities:
//   1. Write access.json (the allowlist + DM policy) into the module's data dir
//   2. Register an `imessage` entry in the agent's .mcp.json so the agent can
//      see chat_messages / reply / manage_allowlist tools
//
// Receives: (systemConfig, userConfig, installedPath)
//   userConfig.allowFrom — array returned by setup.js

import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";

function nameLower(systemConfig) {
  return (systemConfig.name ?? "agent").toLowerCase().replace(/\s+/g, "-");
}

export async function install(systemConfig, userConfig, installedPath) {
  const installPath = systemConfig.installPath;
  const agentName = nameLower(systemConfig);
  const agentDir = join(installPath, "agents", agentName);
  const stateDir = join(installedPath, "data");
  const accessFile = join(stateDir, "access.json");
  const fifoPath = `/tmp/${agentName}-input`;

  // 1. Write access.json. Use atomic-ish write — directory creation + plain write
  //    is fine on first install; saveAccess() inside the server uses temp+rename
  //    for runtime mutations.
  const allowFrom = Array.isArray(userConfig?.allowFrom) ? userConfig.allowFrom : [];
  const access = {
    dmPolicy: "allowlist",
    allowFrom,
    groups: {},
    pending: {},
  };
  mkdirSync(stateDir, { recursive: true, mode: 0o700 });
  writeFileSync(accessFile, JSON.stringify(access, null, 2) + "\n", { mode: 0o600 });
  console.log(`  imessage: wrote ${accessFile} (${allowFrom.length} contacts)`);

  // 2. Register / update the imessage MCP entry in the agent's .mcp.json.
  //    Tolerate the file being missing — start.sh expects it, so the conductor
  //    template will create it; if not, we initialize a minimal one.
  const mcpFile = join(agentDir, ".mcp.json");
  const tsxBin = join(installedPath, "node_modules", ".bin", "tsx");
  const serverScript = join(installedPath, "server.ts");

  let mcp = { mcpServers: {} };
  if (existsSync(mcpFile)) {
    try {
      mcp = JSON.parse(readFileSync(mcpFile, "utf8"));
      if (!mcp.mcpServers || typeof mcp.mcpServers !== "object") {
        mcp.mcpServers = {};
      }
    } catch (err) {
      console.warn(
        `  imessage: ${mcpFile} was unparseable — recreating from scratch (${err.message})`
      );
      mcp = { mcpServers: {} };
    }
  } else {
    mkdirSync(agentDir, { recursive: true });
    console.log(
      `  imessage: ${mcpFile} did not exist — creating with imessage entry only`
    );
  }

  mcp.mcpServers.imessage = {
    command: tsxBin,
    args: [serverScript],
    env: {
      IMESSAGE_STATE_DIR: stateDir,
      ONE_INPUT_FIFO: fifoPath,
    },
  };

  writeFileSync(mcpFile, JSON.stringify(mcp, null, 2) + "\n");
  console.log(`  imessage: registered MCP entry in ${mcpFile}`);

  // 3. Install the /imessage:access skill into the agent's project-local
  //    skills dir. Claude Code auto-discovers skills under <cwd>/.claude/skills/.
  const skillSrc = join(installedPath, "skill");
  if (existsSync(skillSrc)) {
    const skillDest = join(agentDir, ".claude", "skills", "imessage-access");
    mkdirSync(skillDest, { recursive: true });
    cpSync(skillSrc, skillDest, { recursive: true });
    console.log(`  imessage: installed /imessage:access skill at ${skillDest}`);
  }

  console.log(
    "  imessage: install complete. Grant Full Disk Access to /usr/libexec/sshd-keygen-wrapper\n" +
    "             (or the terminal running the agent) and sign into Messages.app."
  );
}
