#!/usr/bin/env node
/**
 * Stop-hook — cost-daily.json updater.
 *
 * On each Stop event, aggregates today's episodes from the current month's
 * JSONL and writes/updates `~/.claude/runtime/cost-daily.json`.
 *
 * Spec: docs/superpowers/specs/2026-05-24-llm-first-router-overhaul-design.md §12.
 * Closes brain-retro #9 Candidate 4 («cost-daily.json пуст — cost-tracker не пишет»).
 *
 * Fail-quiet: all I/O is try/catch; never crashes the Stop-hook pipeline.
 */

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

import { aggregateDay } from './cost-aggregator.mjs';
import { PRICING } from './cost-pricing.mjs';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export function todayISO(now = new Date()) {
  const y = now.getUTCFullYear();
  const m = String(now.getUTCMonth() + 1).padStart(2, '0');
  const d = String(now.getUTCDate()).padStart(2, '0');
  return `${y}-${m}-${d}`;
}

export function currentMonthFile(now = new Date(), repoRoot = process.cwd()) {
  const y = now.getUTCFullYear();
  const m = String(now.getUTCMonth() + 1).padStart(2, '0');
  return join(repoRoot, 'docs', 'observer', `episodes-${y}-${m}.jsonl`);
}

export function readEpisodesJsonl(path) {
  if (!path || !existsSync(path)) return [];
  try {
    const raw = readFileSync(path, 'utf-8');
    const out = [];
    for (const line of raw.split('\n')) {
      const s = line.trim();
      if (!s) continue;
      try { out.push(JSON.parse(s)); } catch { /* skip malformed */ }
    }
    return out;
  } catch { return []; }
}

export function loadCostDaily(path) {
  if (!path || !existsSync(path)) return {};
  try {
    const raw = readFileSync(path, 'utf-8');
    const j = JSON.parse(raw);
    return (j && typeof j === 'object') ? j : {};
  } catch { return {}; }
}

export function runUpdate({ episodes, dateISO, existing, pricing }) {
  const day = aggregateDay(episodes, dateISO, pricing);
  return { ...existing, [dateISO]: day };
}

function writeCostDaily(path, data) {
  try {
    mkdirSync(dirname(path), { recursive: true });
    writeFileSync(path, JSON.stringify(data, null, 2));
    return true;
  } catch { return false; }
}

async function main() {
  try {
    const repoRoot = process.cwd();
    const now = new Date();
    const date = todayISO(now);
    const monthFile = currentMonthFile(now, repoRoot);
    const episodes = readEpisodesJsonl(monthFile);
    const costDailyPath = join(homedir(), '.claude', 'runtime', 'cost-daily.json');
    const existing = loadCostDaily(costDailyPath);
    const updated = runUpdate({ episodes, dateISO: date, existing, pricing: PRICING });
    writeCostDaily(costDailyPath, updated);
    // Stop-hook contract: print empty JSON to stdout on success, exit 0.
    process.stdout.write('{}');
    process.exit(0);
  } catch {
    // Fail-quiet: never crash the Stop pipeline.
    process.stdout.write('{}');
    process.exit(0);
  }
}

const isCli = process.argv[1] && process.argv[1].replace(/\\/g, '/').endsWith('/cost-stop-hook.mjs');
if (isCli) main();
