import fs from "node:fs";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { MODEL_FUSION_SCHEMA_BUNDLE_HASH } from "../fixtures/modelFusion.js";
const PACKAGE_JSON_PATH = "package.json";
const PROTOCOL_ORIGIN_PATH = "docs/model-fusion-protocol-origin.json";
const PUBLIC_NPM_REGISTRY = "https://registry.npmjs.org";
const CANONICAL_PACKAGE_NAME = "@velum-labs/cursorkit";
const CANONICAL_REPOSITORY_URL = "git+https://github.com/velum-labs/cursorkit.git";
const PROTOCOL_PACKAGE_NAME = "@velum-labs/model-fusion-protocol";
const PROTOCOL_CONTRACTS = "json-schema+openapi-3.1";
export function checkReleasePublishConfig(repoRoot = process.cwd()) {
    const errors = [];
    const packageJson = readJson(repoRoot, PACKAGE_JSON_PATH, errors);
    const protocolOrigin = readJson(repoRoot, PROTOCOL_ORIGIN_PATH, errors);
    if (packageJson === undefined || protocolOrigin === undefined) {
        return errors;
    }
    checkPackageMetadata(packageJson, errors);
    checkProtocolPin(packageJson, protocolOrigin, errors);
    return errors;
}
function checkPackageMetadata(packageJson, errors) {
    if (packageJson.name !== CANONICAL_PACKAGE_NAME) {
        errors.push(`${PACKAGE_JSON_PATH}: name must be ${CANONICAL_PACKAGE_NAME}`);
    }
    if (packageJson.repository?.url !== CANONICAL_REPOSITORY_URL) {
        errors.push(`${PACKAGE_JSON_PATH}: repository.url must be ${CANONICAL_REPOSITORY_URL}`);
    }
    // @velum-labs/cursorkit publishes to public npm (no manual deploys): the release
    // workflow runs only on a reviewed GitHub Release and publishes with
    // provenance, so the publish posture is asserted here.
    if (packageJson.publishConfig?.registry !== PUBLIC_NPM_REGISTRY) {
        errors.push(`${PACKAGE_JSON_PATH}: publishConfig.registry must be ${PUBLIC_NPM_REGISTRY}`);
    }
    if (packageJson.publishConfig?.access !== "public") {
        errors.push(`${PACKAGE_JSON_PATH}: publishConfig.access must be public`);
    }
    if (packageJson.publishConfig?.provenance !== true) {
        errors.push(`${PACKAGE_JSON_PATH}: publishConfig.provenance must be true for supply-chain provenance`);
    }
    if (packageJson.private !== false) {
        errors.push(`${PACKAGE_JSON_PATH}: private must be false so the release workflow can publish`);
    }
}
function checkProtocolPin(packageJson, protocolOrigin, errors) {
    const pin = packageJson.modelFusionProtocol;
    if (pin === undefined) {
        errors.push(`${PACKAGE_JSON_PATH}: modelFusionProtocol pin is required`);
        return;
    }
    if (pin.packageName !== PROTOCOL_PACKAGE_NAME) {
        errors.push(`${PACKAGE_JSON_PATH}: modelFusionProtocol.packageName must be ${PROTOCOL_PACKAGE_NAME}`);
    }
    if (pin.version === undefined ||
        !/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(pin.version)) {
        errors.push(`${PACKAGE_JSON_PATH}: modelFusionProtocol.version must be a pinned semver version`);
    }
    if (pin.schemaBundleHash !== MODEL_FUSION_SCHEMA_BUNDLE_HASH) {
        errors.push(`${PACKAGE_JSON_PATH}: modelFusionProtocol.schemaBundleHash must match ${MODEL_FUSION_SCHEMA_BUNDLE_HASH}`);
    }
    if (pin.schemaBundleHash !== protocolOrigin.schemaBundleHash) {
        errors.push(`${PACKAGE_JSON_PATH}: modelFusionProtocol.schemaBundleHash must match ${PROTOCOL_ORIGIN_PATH}`);
    }
    if (pin.packageName !== protocolOrigin.packages?.typescript?.name) {
        errors.push(`${PACKAGE_JSON_PATH}: modelFusionProtocol.packageName must match ${PROTOCOL_ORIGIN_PATH}`);
    }
    if (pin.contracts !== PROTOCOL_CONTRACTS) {
        errors.push(`${PACKAGE_JSON_PATH}: modelFusionProtocol.contracts must be ${PROTOCOL_CONTRACTS}`);
    }
    if (pin.origin !== "fusionkit") {
        errors.push(`${PACKAGE_JSON_PATH}: modelFusionProtocol.origin must be fusionkit`);
    }
    if (protocolOrigin.serviceIdl?.sourceOfTruth !== "openapi-3.1") {
        errors.push(`${PROTOCOL_ORIGIN_PATH}: serviceIdl.sourceOfTruth must be openapi-3.1 for v1 release publishing`);
    }
    if (protocolOrigin.persistedRecordFormat?.sourceOfTruth !== "json-schema") {
        errors.push(`${PROTOCOL_ORIGIN_PATH}: persistedRecordFormat.sourceOfTruth must be json-schema for v1 release publishing`);
    }
}
function readJson(repoRoot, relativePath, errors) {
    try {
        return JSON.parse(fs.readFileSync(path.resolve(repoRoot, relativePath), "utf8"));
    }
    catch (error) {
        errors.push(`${relativePath}: ${error instanceof Error ? error.message : String(error)}`);
        return undefined;
    }
}
if (process.argv[1] !== undefined &&
    import.meta.url === pathToFileURL(process.argv[1]).href) {
    const errors = checkReleasePublishConfig();
    if (errors.length > 0) {
        for (const error of errors) {
            console.error(error);
        }
        process.exitCode = 1;
    }
}
