// Interaction Awareness — SessionEnd hook (Layer 2, Node.js)
// Finalizes session record, computes duration, cleans up state.

import { existsSync } from 'fs';
import {
  readStdin, initConfig, requireLayer, getSessionId,
  nowEpoch, nowIso,
  STATE_DIR, SESSIONS_LOG,
  readState, sessionStateFile, appendJsonl, removeFile
} from './lib.mjs';

readStdin();
initConfig();
requireLayer(2);

const sid = getSessionId();
if (!sid) process.exit(0);

const nowTs = nowEpoch();
const nowIsoStr = nowIso();
const sf = sessionStateFile();

if (!existsSync(sf)) {
  appendJsonl(SESSIONS_LOG, {
    session_id: sid,
    end: nowIsoStr,
    note: 'no_state_file'
  });
  process.exit(0);
}

// Read final state
const state = readState();
const startEpoch = Number(state.start_epoch) || 0;
const toolCount = Number(state.tool_count) || 0;
const editCount = Number(state.edit_count) || 0;
const depFlags = Number(state.dep_flags) || 0;
const escFlags = Number(state.esc_flags) || 0;
const fatFlags = Number(state.fatigue_flags) || 0;
const valFlags = Number(state.val_flags) || 0;
const pushbackCount = Number(state.pushback_count) || 0;
// v1.2: domain_context is always written as array. Coerce v1.1.0 string shape.
const domainContextRaw = state.domain_context;
const domainContextArray = Array.isArray(domainContextRaw)
  ? domainContextRaw
  : (domainContextRaw ? [domainContextRaw] : []);
const startIso = state.start_iso || '';

// Compute duration
let durationMin = 0;
if (startEpoch > 0) {
  durationMin = Math.floor((nowTs - startEpoch) / 60);
}

// v1.2: also persist user_info_class (read-only — set during prompt-analyzer).
const userInfoClass = state.user_info_class || null;
const valseekCount = Number(state.valseek_count) || 0;
const turnCount = Number(state.turn_count) || 0;

// Append finalized session record
appendJsonl(SESSIONS_LOG, {
  session_id: sid,
  start: startIso,
  end: nowIsoStr,
  duration_min: durationMin,
  tool_count: toolCount,
  edit_count: editCount,
  domain_context: domainContextArray,
  user_info_class: userInfoClass,
  valseek_count: valseekCount,
  turn_count: turnCount,
  flags: {
    dependency: depFlags,
    escalation: escFlags,
    fatigue: fatFlags,
    validation: valFlags,
    pushback: pushbackCount
  }
});

// Clean up state file
removeFile(sf);
process.exit(0);
