/**
 * Session transcript — append-only JSONL file in the workspace.
 *
 * Each line is one AI SDK {@link ModelMessage}, JSON-encoded. The transcript lives at
 * `workspaceDir/.cph/sessions/<sessionId>.jsonl`, following the same "workspace
 * is a directory tree" principle as the engineering file itself (ADR-0007).
 *
 * This mirrors how Claude Code stores its transcript (a `.jsonl` file per
 * session). The agent can read its own history via `read_file` — no special
 * "load history" code path. ADR-0002's lock guarantees one run per project at a
 * time, so the transcript is never concurrently written.
 *
 * ADR-0003: this stores **agent session messages** (prompt + response + tool
 * calls produced by the Hub), NOT Feishu group chat history. The two are
 * distinct; storing session messages does not conflict with "the Hub avoids
 * becoming a full chat history store."
 */
import { readFile, mkdir, appendFile } from "node:fs/promises";
import { join, dirname } from "node:path";
import type { ModelMessage } from "ai";

/// Subdirectory within a workspace where session transcripts live.
export const TRANSCRIPT_DIR = ".cph/sessions";

/** Path for a session's transcript file within a workspace. */
export function transcriptPath(workspaceDir: string, sessionId: string): string {
  return join(workspaceDir, TRANSCRIPT_DIR, `${sessionId}.jsonl`);
}

/**
 * Read prior messages from a transcript file. Returns an empty array if the
 * file doesn't exist yet (first run in this session). Corrupt lines are
 * skipped — a partially-written last line (crash mid-append) won't break the
 * next run.
 */
export async function readTranscript(path: string): Promise<ModelMessage[]> {
  let content: string;
  try {
    content = await readFile(path, "utf8");
  } catch {
    return [];
  }
  const messages: ModelMessage[] = [];
  for (const line of content.split("\n")) {
    const trimmed = line.trim();
    if (trimmed === "") continue;
    try {
      messages.push(JSON.parse(trimmed) as ModelMessage);
    } catch {
      // Skip corrupt line — likely a partial write from a crash.
    }
  }
  return messages;
}

/**
 * Append messages to a transcript file. Creates the parent directory if needed.
 * Each message is written as one JSON line.
 */
export async function appendTranscript(path: string, messages: readonly ModelMessage[]): Promise<void> {
  await mkdir(dirname(path), { recursive: true });
  const lines = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
  await appendFile(path, lines, "utf8");
}
