import { randomUUID } from 'crypto';
import { createHmac, timingSafeEqual } from 'crypto';
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
import { join, dirname } from 'path';
export class WebhookManager {
    webhooks = new Map();
    configPath;
    constructor(configDir) {
        this.configPath = join(configDir || '.codebuddy', 'webhooks.json');
        this.load();
    }
    register(name, agentMessage, secret) {
        const config = {
            id: randomUUID(),
            name,
            secret,
            agentMessage,
            enabled: true,
            createdAt: Date.now(),
        };
        this.webhooks.set(config.id, config);
        this.save();
        return config;
    }
    remove(id) {
        const deleted = this.webhooks.delete(id);
        if (deleted) {
            this.save();
        }
        return deleted;
    }
    setEnabled(id, enabled) {
        const hook = this.webhooks.get(id);
        if (!hook)
            return false;
        hook.enabled = enabled;
        this.save();
        return true;
    }
    get(id) {
        return this.webhooks.get(id);
    }
    list() {
        return Array.from(this.webhooks.values());
    }
    processPayload(id, body, signature) {
        const hook = this.webhooks.get(id);
        if (!hook) {
            return { error: 'Webhook not found' };
        }
        if (!hook.enabled) {
            return { error: 'Webhook is disabled' };
        }
        if (hook.secret) {
            if (!signature) {
                return { error: 'Missing signature' };
            }
            const payload = JSON.stringify(body);
            if (!this.verifySignature(payload, signature, hook.secret)) {
                return { error: 'Invalid signature' };
            }
        }
        const message = this.resolveTemplate(hook.agentMessage, body);
        return { message };
    }
    verifySignature(payload, signature, secret) {
        const expected = createHmac('sha256', secret).update(payload).digest('hex');
        try {
            const sigBuf = Buffer.from(signature, 'hex');
            const expBuf = Buffer.from(expected, 'hex');
            if (sigBuf.length !== expBuf.length)
                return false;
            return timingSafeEqual(sigBuf, expBuf);
        }
        catch {
            return false;
        }
    }
    resolveTemplate(template, body) {
        return template.replace(/\{\{body\.([^}]+)\}\}/g, (_match, path) => {
            const parts = path.split('.');
            let current = body;
            for (const part of parts) {
                if (current === null || current === undefined || typeof current !== 'object') {
                    return `{{body.${path}}}`;
                }
                // Block prototype pollution paths
                if (part === '__proto__' || part === 'constructor' || part === 'prototype') {
                    return `{{body.${path}}}`;
                }
                current = current[part];
            }
            if (current === null || current === undefined) {
                return `{{body.${path}}}`;
            }
            return String(current);
        });
    }
    load() {
        try {
            if (existsSync(this.configPath)) {
                const data = JSON.parse(readFileSync(this.configPath, 'utf-8'));
                if (Array.isArray(data)) {
                    for (const hook of data) {
                        this.webhooks.set(hook.id, hook);
                    }
                }
            }
        }
        catch {
            // Start with empty webhooks on load failure
        }
    }
    save() {
        try {
            const dir = dirname(this.configPath);
            if (!existsSync(dir)) {
                mkdirSync(dir, { recursive: true });
            }
            writeFileSync(this.configPath, JSON.stringify(this.list(), null, 2));
        }
        catch {
            // Silently fail on save errors
        }
    }
}
//# sourceMappingURL=webhook-manager.js.map