// Verify Docker Attestations tests cover verify docker attestations script behavior.
import { describe, expect, it } from "vitest";
import {
  collectDockerAttestationErrors,
  imageRefForDigest,
  inspectRaw,
  parseArgs,
  parsePlatform,
} from "../../scripts/verify-docker-attestations.mjs";

const imageDigest = "sha256:1111111111111111111111111111111111111111111111111111111111111111";
const attestationDigest = "sha256:2222222222222222222222222222222222222222222222222222222222222222";

function createIndex() {
  return {
    schemaVersion: 2,
    mediaType: "application/vnd.oci.image.index.v1+json",
    manifests: [
      {
        mediaType: "application/vnd.oci.image.manifest.v1+json",
        digest: imageDigest,
        size: 482,
        platform: { architecture: "amd64", os: "linux" },
      },
      {
        mediaType: "application/vnd.oci.image.manifest.v1+json",
        digest: attestationDigest,
        size: 1110,
        annotations: {
          "vnd.docker.reference.digest": imageDigest,
          "vnd.docker.reference.type": "attestation-manifest",
        },
        platform: { architecture: "unknown", os: "unknown" },
      },
    ],
  };
}

function createAttestation(
  predicates = ["https://spdx.dev/Document", "https://slsa.dev/provenance/v1"],
) {
  return {
    schemaVersion: 2,
    mediaType: "application/vnd.oci.image.manifest.v1+json",
    artifactType: "application/vnd.docker.attestation.manifest.v1+json",
    layers: predicates.map((predicate) => ({
      mediaType: "application/vnd.in-toto+json",
      digest: imageDigest,
      size: 1,
      annotations: {
        "in-toto.io/predicate-type": predicate,
      },
    })),
  };
}

describe("verify-docker-attestations", () => {
  it("bounds docker manifest inspection calls", () => {
    const calls: unknown[] = [];
    const imageRef = "ghcr.io/openclaw/openclaw:test";
    const output = inspectRaw(imageRef, {
      execFileSyncImpl(command: string, args: string[], options: unknown) {
        calls.push({ args, command, options });
        return "{}";
      },
    });

    expect(output).toBe("{}");
    expect(calls).toStrictEqual([
      {
        args: ["buildx", "imagetools", "inspect", "--raw", imageRef],
        command: "docker",
        options: {
          encoding: "utf8",
          killSignal: "SIGKILL",
          maxBuffer: 20 * 1024 * 1024,
          stdio: ["ignore", "pipe", "pipe"],
          timeout: 120_000,
        },
      },
    ]);
  });

  it("parses required platforms and image refs", () => {
    expect(
      parseArgs(["--platform", "linux/amd64", "--platform", "linux/arm64", "ghcr.io/openclaw/app"]),
    ).toEqual({
      help: false,
      imageRefs: ["ghcr.io/openclaw/app"],
      requiredPlatforms: [
        { architecture: "amd64", os: "linux", variant: undefined },
        { architecture: "arm64", os: "linux", variant: undefined },
      ],
    });
  });

  it("rejects missing platform option values", () => {
    expect(() => parseArgs(["--platform"])).toThrow("--platform requires a value");
    expect(() => parseArgs(["--platform", "-h"])).toThrow("--platform requires a value");
    expect(() => parseArgs(["--platform", "--help"])).toThrow("--platform requires a value");
    expect(() => parseArgs(["--platform", ""])).toThrow("--platform requires a value");
  });

  it("resolves digest refs from tagged image refs", () => {
    expect(imageRefForDigest("ghcr.io/openclaw/openclaw:2026.4.26", imageDigest)).toBe(
      `ghcr.io/openclaw/openclaw@${imageDigest}`,
    );
    expect(imageRefForDigest("localhost:5000/openclaw:main", imageDigest)).toBe(
      `localhost:5000/openclaw@${imageDigest}`,
    );
  });

  it("accepts an image index with SBOM and provenance predicates", () => {
    const errors = collectDockerAttestationErrors({
      imageRef: "ghcr.io/openclaw/openclaw:test",
      index: createIndex(),
      requiredPlatforms: [parsePlatform("linux/amd64")],
      inspectAttestation: () => createAttestation(),
    });

    expect(errors).toStrictEqual([]);
  });

  it("accepts attestation manifests with omitted artifactType", () => {
    const errors = collectDockerAttestationErrors({
      imageRef: "ghcr.io/openclaw/openclaw:test",
      index: createIndex(),
      requiredPlatforms: [parsePlatform("linux/amd64")],
      inspectAttestation: () => {
        const attestation: Record<string, unknown> = createAttestation();
        delete attestation.artifactType;
        return attestation;
      },
    });

    expect(errors).toStrictEqual([]);
  });

  it("reports unexpected attestation artifact types", () => {
    const errors = collectDockerAttestationErrors({
      imageRef: "ghcr.io/openclaw/openclaw:test",
      index: createIndex(),
      requiredPlatforms: [parsePlatform("linux/amd64")],
      inspectAttestation: () => ({
        ...createAttestation(),
        artifactType: "application/vnd.unknown",
      }),
    });

    expect(errors).toEqual([
      `ghcr.io/openclaw/openclaw:test: linux/amd64 attestation ${attestationDigest} has unexpected artifactType "application/vnd.unknown"`,
    ]);
  });

  it("reports missing attestation manifests", () => {
    const index = createIndex();
    index.manifests = index.manifests.slice(0, 1);

    const errors = collectDockerAttestationErrors({
      imageRef: "ghcr.io/openclaw/openclaw:test",
      index,
      requiredPlatforms: [parsePlatform("linux/amd64")],
      inspectAttestation: () => createAttestation(),
    });

    expect(errors).toEqual([
      "ghcr.io/openclaw/openclaw:test: missing attestation manifest for linux/amd64",
    ]);
  });

  it("reports missing SBOM or provenance predicates", () => {
    const errors = collectDockerAttestationErrors({
      imageRef: "ghcr.io/openclaw/openclaw:test",
      index: createIndex(),
      requiredPlatforms: [parsePlatform("linux/amd64")],
      inspectAttestation: () => createAttestation(["https://spdx.dev/Document"]),
    });

    expect(errors).toEqual([
      "ghcr.io/openclaw/openclaw:test: linux/amd64 missing predicate https://slsa.dev/provenance/v1",
    ]);
  });
});
