import { describe, expect, test } from "bun:test";
import { readFileSync } from "node:fs";
import { projectLogicalDumps } from "./platform-db-postgres-backups";
import { readPostgresLogicalDumps, renderPostgresRemoteRunnerForTest } from "./platform-db";

describe("PostgreSQL logical dumps", () => {
  test("keeps Sub2API on PK01 and declares PikaOA on NC01", () => {
    const pk01LogicalDumps = readPostgresLogicalDumps("config/platform-db/postgres-pk01.yaml");
    const nc01LogicalDumps = readPostgresLogicalDumps("config/platform-db/postgres-nc01.yaml");

    expect(pk01LogicalDumps).toHaveLength(1);
    expect(pk01LogicalDumps[0]).toMatchObject({
      database: "sub2api",
      scriptPath: "/usr/local/sbin/unidesk-pk01-sub2api-pgdump.sh",
      serviceName: "unidesk-pk01-sub2api-pgdump.service",
      timerName: "unidesk-pk01-sub2api-pgdump.timer",
      schedule: "*-*-* 03:17:00",
      retentionDays: 14,
    });
    expect(nc01LogicalDumps.map((item) => item.database)).toEqual(["agentrun_v02", "pikaoa"]);
    expect(nc01LogicalDumps[1]).toMatchObject({
      destination: { path: "/var/backups/unidesk/platform-db/nc01/pikaoa" },
      schedule: "*-*-* 03:47:00",
      retentionDays: 14,
    });
  });

  test("renders YAML-driven backup resources without Sub2API constants", () => {
    const runner = renderPostgresRemoteRunnerForTest();

    expect(runner).toContain('data["backup"]["logicalDumps"][index]');
    expect(runner).toContain("backup.logicalDumps.$backup_index.serviceName");
    expect(runner).toContain("backup.logicalDumps.$backup_index.timerName");
    expect(runner).not.toContain("unidesk-pk01-sub2api-pgdump.service");
    expect(runner).not.toContain("OnCalendar=*-*-* 03:17:00");
  });

  test("PK01 backup YAML has no duplicate future encryption key", () => {
    const source = readFileSync("config/platform-db/postgres-pk01.yaml", "utf8");

    expect(source.match(/^\s+futureKeyRef:/gmu)).toHaveLength(1);
    expect(() => readPostgresLogicalDumps("config/platform-db/postgres-pk01.yaml")).not.toThrow();
  });

  test("reports stale or missing evidence as warnings", () => {
    const [declaration] = readPostgresLogicalDumps("config/platform-db/postgres-pk01.yaml");
    const [projection] = projectLogicalDumps([declaration], [{
      database: declaration.database,
      databaseExists: true,
      scriptPath: declaration.scriptPath,
      scriptExists: true,
      serviceName: declaration.serviceName,
      serviceResult: "success",
      serviceExitStatus: 0,
      lastSuccessAt: null,
      timerName: declaration.timerName,
      timerActive: true,
      timerEnabled: true,
      nextRunAt: null,
      latestNonEmptyDump: null,
    }]);

    expect(projection.recoverability.recoverable).toBeFalse();
    expect(projection.warnings).toContain("backup-recent-success-missing");
    expect(projection.warnings).toContain("backup-latest-non-empty-dump-missing");
  });
});
