import { existsSync, readFileSync } from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";
import type { ActivityEvent, ActivitySourceResult, KubernetesSourceOptions } from "../types";

export const KUBERNETES_SOURCE = { id: "kubernetes", label: "Kubernetes lifecycle", category: "service" } as const;
export function defaultKubernetesActivityPath(): string {
  return join(homedir(), ".local", "state", "overdeck", "activity", "kubernetes.jsonl");
}

function normalizeKubernetesLifecycle(event: ActivityEvent): ActivityEvent {
  if (event.lifecycle !== undefined || event.result !== undefined) return event;
  const state = [event.detail?.phase, event.detail?.status, event.detail?.reason].filter((value): value is string => typeof value === "string").join(" ").toLowerCase();
  if (/failed|error|crash|evicted/.test(state)) return { ...event, lifecycle: "failed", result: "failure", severity: "error" };
  if (/succeeded|complete|completed/.test(state)) return { ...event, lifecycle: "completed", result: "success" };
  if (/running|active/.test(state)) return { ...event, lifecycle: "active", result: "unknown" };
  if (/pending|created|scheduled|started/.test(state)) return { ...event, lifecycle: "started", result: "unknown" };
  return { ...event, lifecycle: "unknown", result: "unknown" };
}

export function readKubernetesSource(options: KubernetesSourceOptions = {}): ActivitySourceResult {
  const path = options.path ?? defaultKubernetesActivityPath();
  const present = options.existsSyncImpl ?? existsSync;
  if (!present(path)) return { events: [], skippedEntries: [], skippedTruncated: false, coverage: { ...KUBERNETES_SOURCE, path, status: "absent", records: 0, totalRecords: 0, skipped: 0, error: "Kubernetes lifecycle history has not been recorded yet." } };
  let raw: string;
  try { raw = (options.readFileImpl ?? ((p) => readFileSync(p, "utf8")))(path); }
  catch (error) { return { events: [], skippedEntries: [], skippedTruncated: false, coverage: { ...KUBERNETES_SOURCE, path, status: "error", records: 0, totalRecords: 0, skipped: 0, error: String(error) } }; }
  const valid: ActivityEvent[] = [];
  let skipped = 0;
  for (const line of raw.split("\n")) {
    if (!line.trim()) continue;
    try {
      const event = JSON.parse(line) as ActivityEvent;
      if (!event.id || !Number.isFinite(Date.parse(event.ts)) || event.source !== "kubernetes") { skipped++; continue; }
      valid.push(normalizeKubernetesLifecycle(event));
    } catch { skipped++; }
  }
  const all = [...new Map(valid.map((event) => [event.id, event])).values()];
  const ranged = all.filter((event) => { const ms = Date.parse(event.ts); return (options.fromMs === undefined || ms >= options.fromMs) && (options.toMs === undefined || ms <= options.toMs); });
  const times = all.map((event) => Date.parse(event.ts)).sort((a, b) => a - b);
  return { events: ranged, skippedEntries: [], skippedTruncated: false, coverage: { ...KUBERNETES_SOURCE, path, status: "ok", records: ranged.length, totalRecords: all.length, skipped, ...(times.length ? { earliest: new Date(times[0]!).toISOString(), latest: new Date(times.at(-1)!).toISOString() } : {}) } };
}
