import { createHmac } from "node:crypto";
export const PRODUCER_KEY_HEADER = "x-notify-key";
export const PRODUCER_TIMESTAMP_HEADER = "x-notify-timestamp";
export const PRODUCER_SIGNATURE_HEADER = "x-notify-signature";
export const DEFAULT_BASE_URL = "https://bell.kbsoap.com";
const DEFAULT_TIMEOUT_MS = 3000;
export function signProducerRequest(secret, keyId, timestampSeconds, rawBody) {
    return createHmac("sha256", secret)
        .update(`${keyId}\n${timestampSeconds}\n${rawBody}`, "utf8")
        .digest("hex");
}
export class NotifyEmitError extends Error {
    status;
    code;
    constructor(status, code, message) {
        super(message);
        this.name = "NotifyEmitError";
        this.status = status;
        this.code = code;
    }
}
export function producerHeaders(keyId, secret, rawBody, timestampSeconds = Math.floor(Date.now() / 1000)) {
    return {
        "content-type": "application/json",
        [PRODUCER_KEY_HEADER]: keyId,
        [PRODUCER_TIMESTAMP_HEADER]: String(timestampSeconds),
        [PRODUCER_SIGNATURE_HEADER]: signProducerRequest(secret, keyId, timestampSeconds, rawBody),
    };
}
export function createProducerEmitter(options) {
    const { keyId, secret } = options;
    if (!keyId || !secret)
        throw new Error("A producer emitter needs a key id and a secret");
    const base = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
    const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
    return async (event) => {
        const rawBody = JSON.stringify(event);
        const response = await fetch(`${base}/notify/v1/emit`, {
            method: "POST",
            headers: producerHeaders(keyId, secret, rawBody),
            body: rawBody,
            signal: AbortSignal.timeout(timeoutMs),
        });
        const text = await response.text();
        if (!response.ok) {
            const parsed = parseError(text);
            throw new NotifyEmitError(response.status, parsed.code ?? `http_${response.status}`, parsed.message ?? `Bell answered ${response.status}`);
        }
        return JSON.parse(text);
    };
}
function parseError(text) {
    try {
        const body = JSON.parse(text);
        return body.error ?? {};
    }
    catch {
        return {};
    }
}
