"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EVENT_HOOK_DRAFT_SCHEMA_VERSION = exports.EVENT_HOOK_DRAFT_KIND = void 0;
exports.buildEventHookDraftHookDigest = buildEventHookDraftHookDigest;
exports.stringifyEventHookDraftFile = stringifyEventHookDraftFile;
exports.readEventHookDraftFile = readEventHookDraftFile;
exports.parseEventHookDraftFileJson = parseEventHookDraftFileJson;
const node_crypto_1 = require("node:crypto");
const zod_1 = require("zod");
const draft_file_support_1 = require("./draft-file-support");
exports.EVENT_HOOK_DRAFT_KIND = "alpaca.eventHookDraft";
exports.EVENT_HOOK_DRAFT_SCHEMA_VERSION = 1;
const eventHookDraftTargetSchema = zod_1.z.discriminatedUnion("scope", [
    zod_1.z
        .object({
        scope: zod_1.z.literal("repo"),
        cwd: zod_1.z.string().min(1),
    })
        .strict(),
    zod_1.z
        .object({
        scope: zod_1.z.literal("user:all"),
        cwd: zod_1.z.string().min(1),
    })
        .strict(),
    zod_1.z
        .object({
        scope: zod_1.z.literal("user:project"),
        cwd: zod_1.z.string().min(1),
    })
        .strict(),
]);
const eventHookDraftHookSchema = zod_1.z
    .object({
    path: zod_1.z.string().min(1),
    runner: zod_1.z.string().min(1),
    on: zod_1.z.array(zod_1.z.string().min(1)),
})
    .strict();
const eventHookDraftFileSchema = zod_1.z
    .object({
    kind: zod_1.z.literal(exports.EVENT_HOOK_DRAFT_KIND),
    schemaVersion: zod_1.z.literal(exports.EVENT_HOOK_DRAFT_SCHEMA_VERSION),
    command: zod_1.z.enum(["create", "update"]),
    preparedAt: zod_1.z.string().min(1),
    sourcePrompt: zod_1.z.string().nullable().optional(),
    target: eventHookDraftTargetSchema,
    hook: eventHookDraftHookSchema,
    hookDigest: zod_1.z.string().min(1),
    body: zod_1.z.string().min(1),
    summary: zod_1.z.string().min(1),
    baseDigest: zod_1.z.string().min(1).optional(),
})
    .strict()
    .superRefine((value, context) => {
    if (value.command === "update" && value.baseDigest === undefined) {
        context.addIssue({
            code: "custom",
            path: ["baseDigest"],
            message: "baseDigest is required for update drafts.",
        });
    }
    const expectedHookDigest = buildEventHookDraftHookDigest({
        command: value.command,
        target: value.target,
        hook: value.hook,
    });
    if (value.hookDigest !== expectedHookDigest) {
        context.addIssue({
            code: "custom",
            path: ["hookDigest"],
            message: "hookDigest must match the prepared hook metadata.",
        });
    }
});
function buildEventHookDraftHookDigest(input) {
    const hash = (0, node_crypto_1.createHash)("sha256");
    hash.update(JSON.stringify({
        command: input.command,
        target: input.target,
        hook: {
            path: input.hook.path,
            runner: input.hook.runner,
            on: input.hook.on,
        },
    }));
    return hash.digest("hex");
}
function stringifyEventHookDraftFile(draftFile) {
    return (0, draft_file_support_1.stringifyReusableDraftFile)(draftFile);
}
async function readEventHookDraftFile(draftFilePath) {
    return parseEventHookDraftFileJson(await (0, draft_file_support_1.readReusableDraftFile)(draftFilePath));
}
function parseEventHookDraftFileJson(text) {
    return (0, draft_file_support_1.parseReusableDraftFileJson)({
        text,
        invalidDraftFileMessage: "Invalid event hook draft file.",
        parse: (parsedJson) => eventHookDraftFileSchema.parse(parsedJson),
    });
}
