#!/usr/bin/env node
/**
 * Stop hook addition — router chain progress tracking.
 * Stage 3 of router discipline overhaul.
 *
 * После каждого хода: обновляет state.chainProgress на основе вызванных в этом ходу скилов.
 * Helper для observer-stop-hook — он сам решает, вызывать ли (зависит от того, есть ли router-state).
 */

import { readFileSync, writeFileSync, existsSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
import { fileURLToPath } from 'url';
import { readStdinAsUtf8 } from './router-stdin-helper.mjs';

export function extractSkillInvocations(events) {
  return (events || [])
    .filter((e) => e && e.tool_name === 'Skill')
    .map((e) => {
      const raw = e.tool_input?.skill || '';
      const stripped = raw.includes(':') ? raw.split(':').pop() : raw;
      return stripped;
    })
    .filter(Boolean);
}

export function updateChainProgress(state, skillsInvoked, chains) {
  const chainId = state.classification?.recommendedChain;
  if (!chainId || !chains[chainId]) return { ...state };

  const sequence = chains[chainId].sequence || [];
  const currentProgress = [...(state.chainProgress || [])];

  for (const skill of skillsInvoked) {
    const nextExpectedIdx = currentProgress.length;
    if (nextExpectedIdx >= sequence.length) break;
    if (sequence[nextExpectedIdx] === skill) {
      currentProgress.push(skill);
    }
  }

  return {
    ...state,
    chainProgress: currentProgress,
    chainCompleted: currentProgress.length === sequence.length && sequence.length > 0,
  };
}

async function main() {
  const input = await readStdinAsUtf8(process.stdin);
  const event = JSON.parse(input || '{}');
  const sessionId = event.session_id || 'unknown';
  const events = event.turn_events || [];

  const statePath = join(homedir(), '.claude', 'runtime', `router-state-${sessionId}.json`);
  if (!existsSync(statePath)) { process.stdout.write('{}'); process.exit(0); return; }

  try {
    const state = JSON.parse(readFileSync(statePath, 'utf-8'));
    const { loadRegistry } = await import('./registry-load.mjs');
    const registry = loadRegistry({ useCache: false });
    const skills = extractSkillInvocations(events);
    const updated = updateChainProgress(state, skills, registry.chains || {});
    updated.skillInvokedThisTurn = skills.length > 0;
    writeFileSync(statePath, JSON.stringify(updated, null, 2));
    process.stdout.write('{}');
    process.exit(0);
  } catch (err) {
    process.stderr.write(`[router-stop-gate] ${err.message}\n`);
    process.stdout.write('{}');
    process.exit(0);
  }
}

// CLI guard — Windows-cyrillic path quirk: compare resolved path, not raw argv[1]
const isMain = (() => {
  try {
    return process.argv[1] &&
      fileURLToPath(import.meta.url) === fileURLToPath(`file:///${process.argv[1].replace(/\\/g, '/')}`);
  } catch {
    return process.argv[1] && import.meta.url === `file://${process.argv[1].replace(/\\/g, '/')}`;
  }
})();

if (isMain) {
  main();
}
