#!/usr/bin/env node
// Hook: update-check.mjs
// Event: UserPromptSubmit
// Purpose: Check for newer plugin versions (max 1x/24h, cached).
//
// Protocol:
//   - Read JSON from stdin (consume, don't use)
//   - If newer version available: exit 0, stdout JSON { systemMessage: "..." }
//   - Otherwise: exit 0 silently
//   - Never block the user (always exit 0)
//
// Disable: LLM_SECURITY_UPDATE_CHECK=off

import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { homedir } from 'node:os';

// ---------------------------------------------------------------------------
// Exports for testing
// ---------------------------------------------------------------------------

export const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours

/**
 * Return true if `remote` is a newer semver than `local`.
 * Simple numeric comparison — no pre-release/build metadata.
 */
export function isNewer(remote, local) {
  const r = remote.split('.').map(Number);
  const l = local.split('.').map(Number);
  for (let i = 0; i < Math.max(r.length, l.length); i++) {
    const rv = r[i] ?? 0;
    const lv = l[i] ?? 0;
    if (rv > lv) return true;
    if (rv < lv) return false;
  }
  return false;
}

// ---------------------------------------------------------------------------
// Main (only runs when executed directly, not when imported for tests)
// ---------------------------------------------------------------------------

const __dirname = dirname(fileURLToPath(import.meta.url));
const isDirectExecution = process.argv[1] &&
  resolve(process.argv[1]) === resolve(__dirname, 'update-check.mjs');

if (isDirectExecution) {
  main().catch(() => process.exit(0));
}

async function main() {
  // Opt-out
  if (process.env.LLM_SECURITY_UPDATE_CHECK === 'off') {
    process.exit(0);
  }

  // Consume stdin (prevent pipe errors)
  try { readFileSync(0, 'utf8'); } catch { /* ignore */ }

  // Resolve plugin root
  const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || resolve(__dirname, '../..');

  // Read installed version
  let installed;
  try {
    const pluginJson = JSON.parse(readFileSync(resolve(pluginRoot, '.claude-plugin/plugin.json'), 'utf8'));
    installed = pluginJson.version;
  } catch {
    process.exit(0);
  }

  // Read repo URL
  let repoUrl;
  try {
    const pkg = JSON.parse(readFileSync(resolve(pluginRoot, 'package.json'), 'utf8'));
    repoUrl = pkg.repository?.url;
  } catch {
    process.exit(0);
  }

  if (!installed || !repoUrl) process.exit(0);

  // Cache
  const cacheDir = resolve(homedir(), '.cache/llm-security');
  const cachePath = resolve(cacheDir, 'update-check.json');

  // Check cache
  try {
    if (existsSync(cachePath)) {
      const cache = JSON.parse(readFileSync(cachePath, 'utf8'));
      if (Date.now() - cache.checkedAt < CHECK_INTERVAL_MS) {
        // Cache is fresh
        if (cache.latestVersion && isNewer(cache.latestVersion, installed)) {
          console.log(JSON.stringify({
            systemMessage: `🔄 llm-security v${installed} → v${cache.latestVersion} available. Update: ${repoUrl}`
          }));
        }
        process.exit(0);
      }
    }
  } catch {
    // Corrupt cache — proceed to fetch
  }

  // Fetch latest version from Forgejo raw API
  const fetchUrl = `${repoUrl}/raw/branch/main/.claude-plugin/plugin.json`;
  try {
    const controller = new AbortController();
    const timeout = setTimeout(() => controller.abort(), 3000);
    const res = await fetch(fetchUrl, { signal: controller.signal });
    clearTimeout(timeout);

    if (!res.ok) process.exit(0);

    const remote = JSON.parse(await res.text());
    const latestVersion = remote.version;
    if (!latestVersion) process.exit(0);

    // Write cache
    try {
      mkdirSync(cacheDir, { recursive: true });
      writeFileSync(cachePath, JSON.stringify({ checkedAt: Date.now(), latestVersion }));
    } catch {
      // Cache write failure is non-fatal
    }

    // Notify if newer
    if (isNewer(latestVersion, installed)) {
      console.log(JSON.stringify({
        systemMessage: `🔄 llm-security v${installed} → v${latestVersion} available. Update: ${repoUrl}`
      }));
    }
  } catch {
    // Network error, timeout, parse error — silent exit
  }

  process.exit(0);
}
