// Copyright 2025 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 { createTrustSettings, createCawgTrustSettings, createVerifySettings, mergeSettings, settingsToJson, loadSettingsFromFile, loadSettingsFromUrl, } from "./Settings.js";
import * as fs from "fs-extra";
import * as path from "path";
import * as os from "os";
import { vi } from "vitest";
// Mock node-fetch
vi.mock("node-fetch", () => ({
    default: vi.fn(),
}));
describe("Settings", () => {
    it("creates trust settings", () => {
        var _a, _b, _c;
        const trustConfig = {
            verifyTrustList: true,
            userAnchors: "test",
            allowedList: "allowed",
        };
        const settings = createTrustSettings(trustConfig);
        expect(settings.trust).toBeDefined();
        expect((_a = settings.trust) === null || _a === void 0 ? void 0 : _a.verifyTrustList).toBe(true);
        expect((_b = settings.trust) === null || _b === void 0 ? void 0 : _b.userAnchors).toBe("test");
        expect((_c = settings.trust) === null || _c === void 0 ? void 0 : _c.allowedList).toBe("allowed");
    });
    it("creates CAWG trust settings", () => {
        var _a, _b;
        const trustConfig = {
            verifyTrustList: false,
            trustAnchors: "anchors",
        };
        const settings = createCawgTrustSettings(trustConfig);
        expect(settings.cawgTrust).toBeDefined();
        expect((_a = settings.cawgTrust) === null || _a === void 0 ? void 0 : _a.verifyTrustList).toBe(false);
        expect((_b = settings.cawgTrust) === null || _b === void 0 ? void 0 : _b.trustAnchors).toBe("anchors");
    });
    it("creates verify settings", () => {
        var _a, _b, _c, _d;
        const verifyConfig = {
            verifyAfterReading: true,
            verifyAfterSign: false,
            verifyTrust: true,
            verifyTimestampTrust: false,
            ocspFetch: true,
            remoteManifestFetch: false,
            skipIngredientConflictResolution: true,
            strictV1Validation: false,
        };
        const settings = createVerifySettings(verifyConfig);
        expect(settings.verify).toBeDefined();
        expect((_a = settings.verify) === null || _a === void 0 ? void 0 : _a.verifyAfterReading).toBe(true);
        expect((_b = settings.verify) === null || _b === void 0 ? void 0 : _b.verifyAfterSign).toBe(false);
        expect((_c = settings.verify) === null || _c === void 0 ? void 0 : _c.verifyTrust).toBe(true);
        expect((_d = settings.verify) === null || _d === void 0 ? void 0 : _d.ocspFetch).toBe(true);
    });
    it("creates verify settings with partial config", () => {
        var _a, _b, _c;
        const settings = createVerifySettings({
            verifyAfterReading: false,
        });
        expect(settings.verify).toBeDefined();
        expect((_a = settings.verify) === null || _a === void 0 ? void 0 : _a.verifyAfterReading).toBe(false);
        expect((_b = settings.verify) === null || _b === void 0 ? void 0 : _b.verifyAfterSign).toBeUndefined();
        expect((_c = settings.verify) === null || _c === void 0 ? void 0 : _c.verifyTrust).toBeUndefined();
    });
    it("merges multiple settings", () => {
        var _a, _b;
        const trustSettings = createTrustSettings({
            verifyTrustList: true,
            userAnchors: "test",
        });
        const verifySettings = createVerifySettings({
            verifyAfterReading: false,
            verifyAfterSign: true,
            verifyTrust: true,
            verifyTimestampTrust: true,
            ocspFetch: false,
            remoteManifestFetch: true,
            skipIngredientConflictResolution: false,
            strictV1Validation: false,
        });
        const merged = mergeSettings(trustSettings, verifySettings);
        expect(merged.trust).toBeDefined();
        expect(merged.verify).toBeDefined();
        expect((_a = merged.trust) === null || _a === void 0 ? void 0 : _a.verifyTrustList).toBe(true);
        expect((_b = merged.verify) === null || _b === void 0 ? void 0 : _b.verifyAfterReading).toBe(false);
    });
    it("converts settings to JSON with snake_case keys", () => {
        const settings = createVerifySettings({
            verifyAfterReading: true,
            verifyAfterSign: true,
            verifyTrust: false,
            verifyTimestampTrust: true,
            ocspFetch: false,
            remoteManifestFetch: true,
            skipIngredientConflictResolution: false,
            strictV1Validation: false,
        });
        const json = settingsToJson(settings);
        expect(json).toContain("verify");
        expect(json).toContain("verify_after_reading");
        // Should be parseable with snake_case keys
        const parsed = JSON.parse(json);
        expect(parsed.verify.verify_after_reading).toBe(true);
    });
    it("does not include undefined values in trust settings JSON", () => {
        const trustConfig = {
            verifyTrustList: true,
        };
        const settings = createTrustSettings(trustConfig);
        const json = settingsToJson(settings);
        const parsed = JSON.parse(json);
        expect(parsed.trust.verify_trust_list).toBe(true);
        expect("user_anchors" in parsed.trust).toBe(false);
        expect("trust_anchors" in parsed.trust).toBe(false);
        expect("trust_config" in parsed.trust).toBe(false);
        expect("allowed_list" in parsed.trust).toBe(false);
    });
    it("does not include undefined values in CAWG trust settings JSON", () => {
        const trustConfig = {
            verifyTrustList: false,
        };
        const settings = createCawgTrustSettings(trustConfig);
        const json = settingsToJson(settings);
        const parsed = JSON.parse(json);
        expect(parsed.cawg_trust.verify_trust_list).toBe(false);
        expect("user_anchors" in parsed.cawg_trust).toBe(false);
        expect("trust_anchors" in parsed.cawg_trust).toBe(false);
    });
    it("does not include undefined values in verify settings JSON", () => {
        const verifyConfig = {
            verifyAfterReading: true,
            verifyAfterSign: false,
        };
        const settings = createVerifySettings(verifyConfig);
        const json = settingsToJson(settings);
        const parsed = JSON.parse(json);
        expect(parsed.verify.verify_after_reading).toBe(true);
        expect(parsed.verify.verify_after_sign).toBe(false);
        expect("verify_trust" in parsed.verify).toBe(false);
        expect("verify_timestamp_trust" in parsed.verify).toBe(false);
        expect("ocsp_fetch" in parsed.verify).toBe(false);
        expect("remote_manifest_fetch" in parsed.verify).toBe(false);
    });
    it("does not include undefined values when merging settings", () => {
        const settings1 = {
            trust: {
                verifyTrustList: true,
                userAnchors: "test",
            },
        };
        const settings2 = {
            trust: {
                verifyTrustList: true,
                allowedList: undefined,
            },
            verify: {
                verifyAfterReading: false,
            },
        };
        const merged = mergeSettings(settings1, settings2);
        const json = settingsToJson(merged);
        const parsed = JSON.parse(json);
        expect(parsed.trust.verify_trust_list).toBe(true);
        expect(parsed.trust.user_anchors).toBe("test");
        expect("allowed_list" in parsed.trust).toBe(false);
        expect(parsed.verify.verify_after_reading).toBe(false);
    });
    it("merges settings with later values overriding earlier ones", () => {
        var _a, _b, _c;
        const settings1 = createVerifySettings({
            verifyAfterReading: true,
            verifyAfterSign: true,
            verifyTrust: false,
            verifyTimestampTrust: true,
            ocspFetch: false,
            remoteManifestFetch: true,
            skipIngredientConflictResolution: false,
            strictV1Validation: false,
        });
        const settings2 = {
            verify: {
                verifyTrust: true,
                ocspFetch: true,
            },
        };
        const merged = mergeSettings(settings1, settings2);
        expect((_a = merged.verify) === null || _a === void 0 ? void 0 : _a.verifyAfterReading).toBe(true); // from settings1
        expect((_b = merged.verify) === null || _b === void 0 ? void 0 : _b.verifyTrust).toBe(true); // overridden by settings2
        expect((_c = merged.verify) === null || _c === void 0 ? void 0 : _c.ocspFetch).toBe(true); // overridden by settings2
    });
    describe("loadSettingsFromFile", () => {
        let tempDir;
        beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
            tempDir = yield fs.mkdtemp(path.join(os.tmpdir(), "c2pa-settings-test-"));
        }));
        afterEach(() => __awaiter(void 0, void 0, void 0, function* () {
            yield fs.remove(tempDir);
        }));
        it("loads settings from a JSON file", () => __awaiter(void 0, void 0, void 0, function* () {
            const settingsContent = JSON.stringify({
                verify: {
                    verify_after_reading: false,
                    verify_after_sign: false,
                },
            });
            const filePath = path.join(tempDir, "settings.json");
            yield fs.writeFile(filePath, settingsContent);
            const loaded = yield loadSettingsFromFile(filePath);
            expect(loaded).toBe(settingsContent);
            // Verify it can be parsed
            const parsed = JSON.parse(loaded);
            expect(parsed.verify.verify_after_reading).toBe(false);
        }));
        it("loads settings from a TOML file", () => __awaiter(void 0, void 0, void 0, function* () {
            const tomlContent = `[verify]
verify_after_reading = false
verify_after_sign = false`;
            const filePath = path.join(tempDir, "settings.toml");
            yield fs.writeFile(filePath, tomlContent);
            const loaded = yield loadSettingsFromFile(filePath);
            expect(loaded).toBe(tomlContent);
            expect(loaded).toContain("verify_after_reading");
        }));
        it("throws error for non-existent file", () => __awaiter(void 0, void 0, void 0, function* () {
            const filePath = path.join(tempDir, "nonexistent.json");
            yield expect(loadSettingsFromFile(filePath)).rejects.toThrow();
        }));
    });
    describe("loadSettingsFromUrl", () => {
        beforeEach(() => {
            vi.clearAllMocks();
        });
        it("loads settings from a URL", () => __awaiter(void 0, void 0, void 0, function* () {
            const mockSettings = JSON.stringify({
                verify: {
                    verify_after_reading: true,
                },
            });
            const fetch = (yield import("node-fetch")).default;
            vi.mocked(fetch).mockResolvedValue({
                ok: true,
                text: () => __awaiter(void 0, void 0, void 0, function* () { return mockSettings; }),
            });
            const loaded = yield loadSettingsFromUrl("https://example.com/settings.json");
            expect(loaded).toBe(mockSettings);
            expect(fetch).toHaveBeenCalledWith("https://example.com/settings.json");
        }));
        it("throws error for failed fetch", () => __awaiter(void 0, void 0, void 0, function* () {
            const fetch = (yield import("node-fetch")).default;
            vi.mocked(fetch).mockResolvedValue({
                ok: false,
                status: 404,
                statusText: "Not Found",
            });
            yield expect(loadSettingsFromUrl("https://example.com/missing.json")).rejects.toThrow("Failed to fetch settings from URL: 404 Not Found");
        }));
        it("throws error for network failure", () => __awaiter(void 0, void 0, void 0, function* () {
            const fetch = (yield import("node-fetch")).default;
            vi.mocked(fetch).mockRejectedValue(new Error("Network error"));
            yield expect(loadSettingsFromUrl("https://example.com/settings.json")).rejects.toThrow("Network error");
        }));
    });
});
