// Copyright 2024 Adobe. All rights reserved.
// This file is licensed to you under the Apache License,
// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
// or the MIT license (http://opensource.org/licenses/MIT),
// at your option.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import path from "path";
import * as fs from "fs-extra";
import { Reader } from "./Reader.js";
const tempDir = path.join(__dirname, "tmp");
describe("Reader", () => {
    const manifestStore = JSON.parse(`{
  "active_manifest": "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf",
  "manifests": {
    "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf": {
      "claim_generator": "make_test_images/0.33.1 c2pa-rs/0.33.1",
      "claim_version": 1,
      "claim_generator_info": [
        {
          "name": "make_test_images",
          "version": "0.33.1"
        },
        {
          "name": "c2pa-rs",
          "version": "0.33.1"
        }
      ],
      "title": "CA.jpg",
      "format": "image/jpeg",
      "instance_id": "xmp:iid:ba572347-db0e-4619-b6eb-d38e487da238",
      "thumbnail": {
        "format": "image/jpeg",
        "identifier": "self#jumbf=/c2pa/contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf/c2pa.assertions/c2pa.thumbnail.claim.jpeg"
      },
      "ingredients": [
        {
          "title": "A.jpg",
          "format": "image/jpeg",
          "document_id": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb",
          "instance_id": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb",
          "thumbnail": {
            "format": "image/jpeg",
            "identifier": "self#jumbf=/c2pa/contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf/c2pa.assertions/c2pa.thumbnail.ingredient.jpeg"
          },
          "relationship": "parentOf",
          "label": "c2pa.ingredient"
        }
      ],
      "assertions": [
        {
          "label": "stds.schema-org.CreativeWork",
          "data": {
            "@context": "http://schema.org/",
            "@type": "CreativeWork",
            "author": [
              {
                "name": "John Doe",
                "@type": "Person"
              }
            ]
          },
          "kind": "Json"
        },
        {
          "label": "c2pa.actions.v2",
          "data": {
            "actions": [
              {
                "action": "c2pa.opened",
                "parameters": {
                  "ingredient": {
                    "url": "self#jumbf=c2pa.assertions/c2pa.ingredient",
                    "hash": "5dNlxTKe4afGAicpJa1hF1R3mBZKE+Bl0xmh0McXuO4="
                  }
                }
              },
              {
                "action": "c2pa.color_adjustments",
                "parameters": {
                  "name": "brightnesscontrast"
                }
              }
            ]
          }
        }
      ],
      "signature_info": {
        "alg": "Ps256",
        "issuer": "C2PA Test Signing Cert",
        "common_name": "C2PA Signer",
        "cert_serial_number": "720724073027128164015125666832722375746636448153",
        "time": "2024-08-06T21:53:37+00:00"
      },
      "label": "contentauth:urn:uuid:c2677d4b-0a93-4444-876f-ed2f2d40b8cf"
    }
  }
}`);
    beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
        yield fs.ensureDir(tempDir);
    }));
    afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
        yield fs.remove(tempDir);
    }));
    it("should read from an ArrayBuffer", () => __awaiter(void 0, void 0, void 0, function* () {
        const buffer = yield fs.readFile("./tests/fixtures/CA.jpg");
        const reader = yield Reader.fromAsset({
            buffer,
            mimeType: "jpeg",
        });
        expect(reader).not.toBeNull();
        const json = reader.json();
        expect(json.manifests).toEqual(manifestStore.manifests);
        expect(json.active_manifest).toEqual(manifestStore.active_manifest);
    }));
    it("should read from a file", () => __awaiter(void 0, void 0, void 0, function* () {
        const reader = yield Reader.fromAsset({
            path: "./tests/fixtures/CA.jpg",
        });
        expect(reader).not.toBeNull();
        const json = reader.json();
        expect(json.manifests).toEqual(manifestStore.manifests);
        expect(json.active_manifest).toEqual(manifestStore.active_manifest);
    }));
    it("should return null for a file without C2PA data", () => __awaiter(void 0, void 0, void 0, function* () {
        const reader = yield Reader.fromAsset({
            path: "./tests/fixtures/A.jpg",
        });
        expect(reader).toBeNull();
    }));
    it("should read from manifest data and buffer", () => __awaiter(void 0, void 0, void 0, function* () {
        const manifestData = yield fs.readFile("./tests/fixtures/CA/manifest_data.c2pa");
        const buffer = yield fs.readFile("./tests/fixtures/CA.jpg");
        const reader = yield Reader.fromManifestDataAndAsset(manifestData, {
            buffer,
            mimeType: "jpeg",
        });
        const json = reader.json();
        expect(json.manifests).toEqual(manifestStore.manifests);
        expect(json.active_manifest).toEqual(manifestStore.active_manifest);
    }));
    it("should read from manifest data and file", () => __awaiter(void 0, void 0, void 0, function* () {
        const manifestData = yield fs.readFile("./tests/fixtures/CA/manifest_data.c2pa");
        const reader = yield Reader.fromManifestDataAndAsset(manifestData, {
            path: "./tests/fixtures/CA.jpg",
        });
        const json = reader.json();
        expect(json.manifests).toEqual(manifestStore.manifests);
        expect(json.validation_status[0].code).toEqual("signingCredential.untrusted");
    }));
    it("should read from manifest data and file with settings context", () => __awaiter(void 0, void 0, void 0, function* () {
        const manifestData = yield fs.readFile("./tests/fixtures/CA/manifest_data.c2pa");
        const buffer = yield fs.readFile("./tests/fixtures/CA.jpg");
        const settings = {
            verify: {
                verify_after_reading: false,
                verify_trust: false,
            },
        };
        const reader = yield Reader.fromManifestDataAndAsset(manifestData, {
            buffer,
            mimeType: "jpeg",
        }, settings);
        expect(reader).not.toBeNull();
        const json = reader.json();
        // Settings should affect validation behavior
        // With verify_after_reading: false, validation_status should be undefined
        expect(json.validation_status).toBeUndefined();
        expect(json.manifests).toBeDefined();
        expect(json.active_manifest).toEqual(manifestStore.active_manifest);
    }));
    it("should write to a file", () => __awaiter(void 0, void 0, void 0, function* () {
        var _a;
        const outputPath = path.join(tempDir, "thumbnail.jpg");
        const reader = yield Reader.fromAsset({
            path: "./tests/fixtures/CA.jpg",
        });
        expect(reader).not.toBeNull();
        const activeManifest = reader.getActive();
        const uri = (_a = activeManifest === null || activeManifest === void 0 ? void 0 : activeManifest.thumbnail) === null || _a === void 0 ? void 0 : _a.identifier;
        expect(uri).toBeDefined();
        const bytesWritten = yield reader.resourceToAsset(uri, {
            path: outputPath,
        });
        expect(bytesWritten.bytes_written).toBe(49690);
        expect(fs.existsSync(outputPath));
    }));
    it("should report manifest is embedded", () => __awaiter(void 0, void 0, void 0, function* () {
        const reader = yield Reader.fromAsset({
            path: "./tests/fixtures/CA.jpg",
        });
        expect(reader).not.toBeNull();
        expect(reader.remoteUrl()).toEqual("");
        expect(reader.isEmbedded()).toBeTruthy();
    }));
    it("should report manifest is not embedded", () => __awaiter(void 0, void 0, void 0, function* () {
        const reader = yield Reader.fromAsset({
            path: "./tests/fixtures/cloud.jpg",
        });
        expect(reader).not.toBeNull();
        expect(reader.remoteUrl()).toEqual("https://cai-manifests.adobe.com/manifests/adobe-urn-uuid-5f37e182-3687-462e-a7fb-573462780391");
        expect(reader.isEmbedded()).toBeFalsy();
    }));
    it("should decode CAWG identity assertion with signature_info", () => __awaiter(void 0, void 0, void 0, function* () {
        var _a;
        // This test verifies that postValidateCawg() properly decodes CAWG assertions
        // and extracts signature_info from the signature data, matching c2pa-js behavior
        const reader = yield Reader.fromAsset({
            path: "./tests/fixtures/C_with_CAWG_data.jpg",
        });
        expect(reader).not.toBeNull();
        const activeManifest = reader.getActive();
        // Find the cawg.identity assertion
        const cawgIdentityAssertion = (_a = activeManifest === null || activeManifest === void 0 ? void 0 : activeManifest.assertions) === null || _a === void 0 ? void 0 : _a.find((assertion) => assertion.label === "cawg.identity");
        expect(cawgIdentityAssertion).toBeDefined();
        expect(cawgIdentityAssertion === null || cawgIdentityAssertion === void 0 ? void 0 : cawgIdentityAssertion.data).toBeDefined();
        expect(cawgIdentityAssertion === null || cawgIdentityAssertion === void 0 ? void 0 : cawgIdentityAssertion.data.signature_info).toBeDefined();
        // Verify signature_info structure matches c2pa-js behavior
        const signatureInfo = cawgIdentityAssertion === null || cawgIdentityAssertion === void 0 ? void 0 : cawgIdentityAssertion.data.signature_info;
        const signerPayload = cawgIdentityAssertion === null || cawgIdentityAssertion === void 0 ? void 0 : cawgIdentityAssertion.data.signer_payload;
        // Verify signature_info values
        expect(signatureInfo.alg).toBe("Ed25519");
        expect(signatureInfo.issuer).toBe("C2PA Test Signing Cert");
        expect(signatureInfo.cert_serial_number).toBe("638838410810235485828984295321338730070538954823");
        expect(signatureInfo.revocation_status).toBe(true);
        // Verify signer_payload values
        expect(signerPayload.sig_type).toBe("cawg.x509.cose");
        expect(signerPayload.referenced_assertions).toHaveLength(2);
        expect(signerPayload.referenced_assertions[0]).toEqual({
            url: "self#jumbf=c2pa.assertions/cawg.training-mining",
            hash: "rBBgURB+/0Bc2Uk3+blNpYTGQTxOwzXQ2xhjA3gsqI4=",
        });
        expect(signerPayload.referenced_assertions[1]).toEqual({
            url: "self#jumbf=c2pa.assertions/c2pa.hash.data",
            hash: "sASozh9KFSkW+cyMI0Pw5KYoD2qn7MkUEq9jUUhe/sM=",
        });
    }));
    it("should return null when reading an asset without C2PA metadata", () => __awaiter(void 0, void 0, void 0, function* () {
        // Create a simple JPEG without C2PA data
        const simpleJpeg = Buffer.from([
            0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
            0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff, 0xd9,
        ]);
        const asset = {
            buffer: simpleJpeg,
            mimeType: "image/jpeg",
        };
        const reader = yield Reader.fromAsset(asset);
        expect(reader).toBeNull();
    }));
});
