/**
 * Key-naming conventions for the chat memory summarizer.
 *
 * MemoryStore is a flat key/value API; this module encodes the
 * design's "scope + subject" classification into deterministic key
 * strings so that:
 *   - cursor / health blocks land on a single stable key (upsert covers)
 *   - repeated ingest of the same fact maps to the same key (upsert
 *     replaces, not appends — this is what "memory reinforcement" looks
 *     like at the storage layer)
 *   - buildMemoryContext can post-filter by prefix to keep internal
 *     bookkeeping blocks (cursor / health) out of the LLM prompt
 *
 * See forge-chat-memory-summarizer-design.md §4.2 for the full table.
 */

import { createHash } from 'node:crypto';

/** Stable 12-char content hash. Used in fact keys so re-ingesting the
 *  same fact maps to the same memory block (upsert = reinforcement). */
export function stableHash(input: string): string {
  return createHash('sha256').update(input).digest('hex').slice(0, 12);
}

/** Session summary at a given cursor end-ts. */
export function summaryKey(sessionId: string, toTs: number): string {
  return `chat:${sessionId}:summary:${toTs}`;
}

/** Long-term fact. scope/subject classify it; hash keys re-ingest. */
export function factKey(scope: string, subject: string, contentHash: string): string {
  return `fact:${scope}:${subject}:${contentHash}`;
}

/** Per-session ingest progress cursor. One row per session. */
export function cursorKey(sessionId: string): string {
  return `forge.summarizer.cursor:${sessionId}`;
}

/** Per-session summarizer health (last_run, errors, counts). */
export function healthKey(sessionId: string): string {
  return `forge.summarizer.health:${sessionId}`;
}

/** Prefixes buildMemoryContext should exclude when rendering context —
 *  bookkeeping blocks the LLM shouldn't see. */
export const INTERNAL_KEY_PREFIXES: readonly string[] = [
  'forge.summarizer.cursor:',
  'forge.summarizer.health:',
];

export interface CursorValue {
  last_ingested_ts: number;
  last_run_ts: number;
  ingest_count: number;
}

export interface SummaryValue {
  text: string;
  from_ts: number;
  to_ts: number;
  message_count: number;
  model: string;
  provider: string;
  ingest_ts: number;
}

export interface FactValue {
  content: string;
  subject_kind: string;
  subject: string;
  source_ref: string;
  confidence: number | null;
  extracted_by: 'summarizer' | string;
}

export interface HealthValue {
  last_run_ts: number;
  error: string | null;
  ingest_count: number;
  last_token_estimate: number;
}
