import { describe, expect, it } from "vitest";
import type { ProjectionRecord } from "../api/schemas";
import { asArray, asNumber, asRecord, asString, eeCertificateProjection } from "./projection";

describe("projection guards", () => {
  it("asRecord accepts plain objects only", () => {
    expect(asRecord({ a: 1 })).toEqual({ a: 1 });
    expect(asRecord([1])).toBeNull();
    expect(asRecord("x")).toBeNull();
    expect(asRecord(null)).toBeNull();
  });

  it("asString / asNumber narrow primitives", () => {
    expect(asString("s")).toBe("s");
    expect(asString(1)).toBeNull();
    expect(asNumber(4)).toBe(4);
    expect(asNumber("4")).toBeNull();
    expect(asNumber(NaN)).toBeNull();
  });

  it("asArray defaults to empty", () => {
    expect(asArray([1, 2])).toEqual([1, 2]);
    expect(asArray(undefined)).toEqual([]);
    expect(asArray({})).toEqual([]);
  });
});

describe("eeCertificateProjection", () => {
  const eeCert = { kind: "Ee", subject: "CN=ee" };
  const recordWith = (object: unknown): ProjectionRecord =>
    ({ parseStatus: "ok", projection: { object } }) as unknown as ProjectionRecord;

  it("extracts the Ee certificate from the CMS wrapper", () => {
    const record = recordWith({
      type: "roa",
      signedObject: {
        signedData: {
          certificates: [
            { resourceCertificate: { kind: "Ca", subject: "CN=ca" } },
            { resourceCertificate: eeCert },
          ],
        },
      },
    });
    expect(eeCertificateProjection(record)).toEqual({ resourceCertificate: eeCert });
  });

  it("falls back to the first certificate when no Ee kind is marked", () => {
    const record = recordWith({
      signedObject: { signedData: { certificates: [{ resourceCertificate: eeCert }] } },
    });
    expect(eeCertificateProjection(record)).toEqual({ resourceCertificate: eeCert });
  });

  it("returns null for non-CMS or malformed projections", () => {
    expect(eeCertificateProjection(null)).toBeNull();
    expect(eeCertificateProjection(recordWith({ type: "crl" }))).toBeNull();
    expect(eeCertificateProjection(recordWith(null))).toBeNull();
    expect(
      eeCertificateProjection(recordWith({ signedObject: { signedData: { certificates: [] } } })),
    ).toBeNull();
  });

  it("returns null when the projection failed to parse", () => {
    const record = {
      parseStatus: "error",
      projection: { object: { signedObject: { signedData: { certificates: [{ resourceCertificate: eeCert }] } } } },
    } as unknown as ProjectionRecord;
    expect(eeCertificateProjection(record)).toBeNull();
  });
});
