import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";

/**
 * ECC Safety Hooks — bash rm-rf guard, secret scrubbing, write warnings.
 *
 * Port of ECC PreToolUse hooks from hooks/hooks.json.
 */
export function registerSafetyHooks(pi: ExtensionAPI): void {
  // ── Guard: destructive bash commands ──────────────────────────────────
  pi.on("tool_call", async (event, ctx) => {
    if (event.toolName !== "bash") return;

    const cmd = String(event.input.command ?? "");

    // Block bare `rm -rf /` (with one or two `/` variants)
    if (/rm\s+-rf\s+\/\s*$/.test(cmd) || /rm\s+-rf\s+\/\s*\n/.test(cmd)) {
      return {
        block: true,
        reason: "Blocked by ECC safety: rm -rf / on bare root is never intentional",
      };
    }

    // Warn on `rm -rf` with dynamic variables (potential for catastrophic expansion)
    if (/\$\{?[\w]+\}?\s*\/?\s*$/.test(cmd.replace(/.*rm\s+-rf\s+/, ""))) {
      if (!ctx.hasUI) {
        return { block: true, reason: "Blocked by ECC safety: dynamic rm -rf path (potential expansion risk)" };
      }
      const ok = await ctx.ui.confirm(
        "Dangerous command",
        `Allow: ${cmd.substring(0, 120)}`,
      );
      if (!ok) return { block: true, reason: "User denied dangerous command" };
    }

    // Guard: `dd if=` of a block device
    if (/dd\s+if=\/dev\//.test(cmd)) {
      if (!ctx.hasUI) {
        return { block: true, reason: "Blocked by ECC safety: dd of block device requires confirmation" };
      }
      const ok = await ctx.ui.confirm(
        "Dangerous command",
        `Allow dd block-device write: ${cmd.substring(0, 120)}`,
      );
      if (!ok) return { block: true, reason: "User denied dd command" };
    }

    // Guard: `curl ... | bash` / `wget ... | bash` (remote code execution)
    if (/\b(?:curl|wget)\b.*\|\s*(?:bash|sh|zsh)\b/.test(cmd)) {
      if (!ctx.hasUI) {
        return { block: true, reason: "Blocked by ECC safety: pipe-from-remote requires confirmation" };
      }
      const ok = await ctx.ui.confirm(
        "Remote execution",
        `Allow pipe-from-remote: ${cmd.substring(0, 120)}`,
      );
      if (!ok) return { block: true, reason: "User denied remote execution" };
    }
  });

  // ── Post-execution: scrub secrets from tool output ────────────────────
  pi.on("tool_result", async (event) => {
    if (event.toolName !== "bash" && event.toolName !== "read") return;
    if (event.isError) return;

    const secretPatterns = [
      /(?:gh[ps]_|github_pat_|glpat-)[a-zA-Z0-9_]{36,}/g,
      /(?:sk-[a-zA-Z0-9]{20,}|sk-[a-zA-Z0-9_-]{32,})/g,
      /(?:AKIA[0-9A-Z]{16})/g,
      /(?:-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----)/g,
    ];

    let changed = false;
    const scrubbed = event.content.map((chunk) => {
      if (chunk.type !== "text") return chunk;
      let text = chunk.text;
      for (const pat of secretPatterns) {
        if (pat.test(text)) {
          text = text.replace(pat, "[ECC_REDACTED]");
          changed = true;
        }
      }
      if (changed) return { ...chunk, text };
      return chunk;
    });

    if (changed) {
      return { content: scrubbed };
    }
  });

  // ── Pre-write: warn on modifying agent/config files ───────────────────
  pi.on("tool_call", async (event, ctx) => {
    if (event.toolName !== "write" && event.toolName !== "edit") return;

    const path = String(event.input.path ?? "");
    const sensitivePatterns = [
      /\.claude\/settings\.json$/,
      /\.claude\/CLAUDE\.md$/,
      /\.cursorrules$/,
      /\.windsurfrules$/,
      /opencode\.json$/,
      /\.vscode\/settings\.json$/,
      /\.omp\/(?:settings|config)\.(?:json|ya?ml)$/,
    ];

    if (sensitivePatterns.some((p) => p.test(path)) && ctx.hasUI) {
      const ok = await ctx.ui.confirm(
        "Modify agent config",
        `You are about to modify: ${path}\nProceed?`,
      );
      if (!ok) return { block: true, reason: "User denied agent config modification" };
    }
  });
}
