/**
 * PR-A Baseline Test 10: Session Crash Recovery
 * Verifies: session state survives restart/reload scenarios
 * Freezes: session persistence contract
 */
import { describe, it } from "node:test";
import assert from "node:assert";
import { existsSync, readFileSync, writeFileSync, unlinkSync, statSync, mkdirSync, readdirSync } from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";
import { randomUUID } from "node:crypto";

const WORKSPACE = join(homedir(), ".openclaw", "workspace");
const TEMP_DIR = join(WORKSPACE, "test", "baseline", "tmp");
try { mkdirSync(TEMP_DIR, { recursive: true }); } catch {}

describe("test-10: Session Crash Recovery Baseline", () => {
  it("10.01 - written data survives simulated crash (no fsync)", () => {
    const path = join(TEMP_DIR, "crash-test.json");
    const data = { id: randomUUID(), state: "running", timestamp: Date.now() };
    writeFileSync(path, JSON.stringify(data), "utf8");
    const recovered = JSON.parse(readFileSync(path, "utf8"));
    assert.equal(recovered.id, data.id, "data must survive 'crash'");
    assert.equal(recovered.state, "running", "state must be preserved");
    try { unlinkSync(path); } catch {}
    console.log("[BASELINE] crash recovery: data survives write");
  });

  it("10.02 - partial writes don't produce valid JSON (atomicity check)", () => {
    const path = join(TEMP_DIR, "partial-crash.json");
    writeFileSync(path, '{"id":"test","state":"runn', "utf8");
    try {
      JSON.parse(readFileSync(path, "utf8"));
      assert.fail("partial JSON should not parse");
    } catch (e) {
      console.log("[BASELINE] partial write detected:", e.message.substring(0, 80));
      assert.ok(e instanceof SyntaxError, "partial write must cause parse error");
    }
    try { unlinkSync(path); } catch {}
  });

  it("10.03 - session state file format is JSON", () => {
    const sessionsDir = join(homedir(), ".openclaw", "agents", "main", "sessions");
    if (existsSync(sessionsDir)) {
      const files = readdirSync(sessionsDir);
      const jsonFiles = files.filter(f => f.endsWith(".json"));
      console.log("[BASELINE] session JSON files count:", jsonFiles.length);
      if (jsonFiles.length > 0) {
        for (const f of jsonFiles.slice(0, 3)) {
          try {
            const content = readFileSync(join(sessionsDir, f), "utf8");
            JSON.parse(content);
            console.log(`[BASELINE] ${f}: valid JSON, size=${content.length}`);
          } catch (e) {
            console.log(`[BASELINE] ${f}: invalid JSON — ${e.message.substring(0, 80)}`);
          }
        }
      }
    }
    assert.ok(true, "baseline frozen: session file format");
  });

  it("10.04 - memory index survives process restart simulation", () => {
    const memoryDb = join(homedir(), ".openclaw", "memory", "main.sqlite");
    if (existsSync(memoryDb)) {
      const stat1 = statSync(memoryDb);
      console.log("[BASELINE] memory DB before 'restart': size=%d, mtime=%s",
        stat1.size, stat1.mtime.toISOString());
      const stat2 = statSync(memoryDb);
      assert.equal(stat2.size, stat1.size, "memory DB must survive re-read");
    } else {
      console.log("[BASELINE] no memory DB to check (valid baseline)");
    }
    assert.ok(true, "baseline frozen: memory index survival");
  });

  it("10.05 - workspace files survive across reads (persistence check)", () => {
    const criticalFiles = ["MEMORY.md", "AGENTS.md"];
    for (const f of criticalFiles) {
      const path = join(WORKSPACE, f);
      if (existsSync(path)) {
        const content1 = readFileSync(path, "utf8");
        const content2 = readFileSync(path, "utf8");
        assert.equal(content1.length, content2.length,
          `${f} must be identical across reads`);
        console.log(`[BASELINE] ${f}: persistent read OK, len=${content1.length}`);
      }
    }
  });
});
