/**
 * GitHub inbound webhook: signature verification + event → store payload mapping.
 */
import crypto from "node:crypto";
import { buildExternalActor } from "../../issues/external_actor_builder.js";
export function verifyGithubSignature(rawBody, signatureHeader, secret) {
    if (!signatureHeader || !secret)
        return false;
    const parts = signatureHeader.split("=");
    if (parts.length !== 2 || parts[0] !== "sha256")
        return false;
    const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
    const received = parts[1];
    if (expected.length !== received.length)
        return false;
    return crypto.timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(received, "hex"));
}
export function mapGithubWebhookEventToStore(event, payload, deliveryId) {
    if (event === "issues") {
        return mapIssueEvent(payload, deliveryId);
    }
    if (event === "issue_comment") {
        return mapIssueCommentEvent(payload, deliveryId);
    }
    return null;
}
/** @deprecated Use {@link mapGithubWebhookEventToStore}. */
export const mapEventToStore = mapGithubWebhookEventToStore;
function reporterFieldsFromPayload(payload) {
    const out = {};
    const installation = payload.installation;
    if (installation?.id != null) {
        out.reporter_ci_run_id = `github-installation-${installation.id}`;
    }
    return out;
}
function mapIssueEvent(payload, deliveryId) {
    const action = payload.action;
    if (!["opened", "edited", "closed", "reopened", "labeled", "unlabeled"].includes(action)) {
        return null;
    }
    const issue = payload.issue;
    if (!issue)
        return null;
    const user = issue.user;
    const repo = payload.repository;
    const repoName = repo?.full_name ?? "";
    const actor = buildExternalActor({
        login: user?.login ?? "unknown",
        id: user?.id ?? 0,
        type: user?.type,
        verified_via: "webhook_signature",
        delivery_id: deliveryId,
        event_type: "issues",
        repository: repoName,
        event_id: issue.number,
    });
    const labels = issue.labels?.map((l) => l.name) ?? [];
    const now = new Date().toISOString();
    const issueRow = {
        entity_type: "issue",
        title: issue.title,
        body: issue.body ?? "",
        status: issue.state,
        labels,
        github_number: issue.number,
        github_url: issue.html_url,
        repo: repoName,
        visibility: "public",
        author: user?.login ?? "unknown",
        github_actor: { login: actor.login, id: actor.id, type: actor.type },
        created_at: issue.created_at,
        closed_at: issue.closed_at,
        last_synced_at: now,
        sync_pending: false,
        data_source: `github webhook issues ${repoName} #${issue.number} delivery:${deliveryId}`,
        ...reporterFieldsFromPayload(payload),
    };
    const entities = [
        issueRow,
        {
            entity_type: "conversation",
            title: `Issue #${issue.number}: ${issue.title}`,
            thread_kind: "multi_party",
        },
        {
            entity_type: "conversation_message",
            role: "user",
            sender_kind: "user",
            content: issue.body ?? "",
            author: user?.login ?? "unknown",
            github_actor: { login: actor.login, id: actor.id, type: actor.type },
            github_comment_id: `issue-body-${issue.number}`,
            created_at: issue.created_at,
        },
    ];
    return {
        entities,
        relationships: [
            { relationship_type: "REFERS_TO", source_index: 0, target_index: 1 },
            { relationship_type: "PART_OF", source_index: 2, target_index: 1 },
        ],
        idempotency_key: `webhook-issue-${repoName}-${issue.number}-${deliveryId}`,
        external_actor: actor,
        observation_source: "sensor",
    };
}
function mapIssueCommentEvent(payload, deliveryId) {
    const action = payload.action;
    if (!["created", "edited"].includes(action)) {
        return null;
    }
    const comment = payload.comment;
    const issue = payload.issue;
    if (!comment || !issue)
        return null;
    const user = comment.user;
    const repo = payload.repository;
    const repoName = repo?.full_name ?? "";
    const actor = buildExternalActor({
        login: user?.login ?? "unknown",
        id: user?.id ?? 0,
        type: user?.type,
        verified_via: "webhook_signature",
        delivery_id: deliveryId,
        event_type: "issue_comment",
        repository: repoName,
        event_id: issue.number,
        comment_id: comment.id,
    });
    const entities = [
        {
            entity_type: "conversation",
            title: `Issue #${issue.number}: ${issue.title}`,
            thread_kind: "multi_party",
        },
        {
            entity_type: "conversation_message",
            role: "user",
            sender_kind: "user",
            content: comment.body,
            author: user?.login ?? "unknown",
            github_actor: { login: actor.login, id: actor.id, type: actor.type },
            github_comment_id: String(comment.id),
            created_at: comment.created_at,
        },
    ];
    return {
        entities,
        relationships: [{ relationship_type: "PART_OF", source_index: 1, target_index: 0 }],
        idempotency_key: `webhook-comment-${repoName}-${issue.number}-${comment.id}-${deliveryId}`,
        external_actor: actor,
        observation_source: "sensor",
    };
}
//# sourceMappingURL=github_handler.js.map