import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { join, resolve } from 'node:path';

export const INDEX_SCHEMA_VERSION = '1.1';
export const GITIGNORE_CONTENT = `# boocode audit runs
/*
!index.json
`;

export interface IndexEntry {
  id: string;
  type: string;
  status: string;
  task?: string;
  skill?: string;
  created?: string;
  last_updated?: string;
  record_count?: number;
  anomaly_count?: number;
  max_anomaly_level?: string;
}

export interface IndexFile {
  schema_version: string;
  entries: IndexEntry[];
}

function findRunsDirFrom(start: string): string {
  const explicit = process.env['AUDIT_DOT_DIR']?.trim();
  const candidates = explicit ? [explicit] : ['.boo'];
  let cur = resolve(start);
  while (true) {
    for (const basename of candidates) {
      const candidate = join(cur, basename, 'runs');
      if (existsSync(candidate)) return candidate;
    }
    const parent = resolve(cur, '..');
    if (parent === cur) break;
    cur = parent;
  }
  const defaultBasename = explicit || '.boo';
  return join(resolve(start), defaultBasename, 'runs');
}

export function findRunsDir(projectRoot?: string): string {
  return findRunsDirFrom(projectRoot || process.cwd());
}

export function ensureRunsDir(projectRoot?: string): string {
  const dir = findRunsDir(projectRoot);
  if (!existsSync(dir)) {
    mkdirSync(dir, { recursive: true });
    const gitignorePath = join(dir, '.gitignore');
    if (!existsSync(gitignorePath)) {
      writeFileSync(gitignorePath, GITIGNORE_CONTENT, 'utf-8');
    }
  }
  return dir;
}

export function readCurrentSession(projectRoot?: string): string | null {
  const path = join(ensureRunsDir(projectRoot), '.current_session');
  try {
    return readFileSync(path, 'utf-8').trim();
  } catch {
    return null;
  }
}

export function writeCurrentSession(sessionId: string, projectRoot?: string): void {
  writeFileSync(join(ensureRunsDir(projectRoot), '.current_session'), sessionId, 'utf-8');
}

export function clearCurrentSession(projectRoot?: string): void {
  const path = join(ensureRunsDir(projectRoot), '.current_session');
  try {
    writeFileSync(path, '', 'utf-8');
  } catch {
    // silent
  }
}

export function readIndex(projectRoot?: string): IndexFile {
  const path = join(ensureRunsDir(projectRoot), 'index.json');
  try {
    return JSON.parse(readFileSync(path, 'utf-8')) as IndexFile;
  } catch {
    return { schema_version: INDEX_SCHEMA_VERSION, entries: [] };
  }
}

export function writeIndex(index: IndexFile, projectRoot?: string): void {
  const runsDir = ensureRunsDir(projectRoot);
  writeFileSync(join(runsDir, 'index.json'), JSON.stringify(index, null, 2), 'utf-8');
}

export function updateIndexEntry(entry: IndexEntry, projectRoot?: string): void {
  const idx = readIndex(projectRoot);
  const existing = idx.entries.find(e => e.id === entry.id);
  if (existing) {
    Object.assign(existing, entry);
  } else {
    idx.entries.push({ ...entry });
  }
  writeIndex(idx, projectRoot);
}

export function findInProgressSessions(projectRoot?: string): IndexEntry[] {
  const idx = readIndex(projectRoot);
  return idx.entries.filter(e => e.status === 'in_progress');
}
