/**
 * HTTP Alert Channel Base
 *
 * Abstract base class for HTTP-based alert channels providing:
 * - Fetch with timeout
 * - Response parsing
 * - HTTP error handling
 * - Headers management
 *
 * @packageDocumentation
 * @module security/alerting/channels/http-base
 */
import { BaseAlertChannel } from './base.js';
// =============================================================================
// HttpAlertChannel Class
// =============================================================================
/**
 * Abstract base class for HTTP-based alert channels
 *
 * Extends BaseAlertChannel with HTTP-specific functionality:
 * - Fetch with timeout and abort controller
 * - JSON request/response handling
 * - HTTP error extraction
 */
export class HttpAlertChannel extends BaseAlertChannel {
    constructor(config = {}) {
        super(config);
    }
    /**
     * Make an HTTP request with timeout
     */
    async httpRequest(options) {
        const { url, method = 'POST', headers = {}, body, timeout = this.timeout, } = options;
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), timeout);
        try {
            const requestHeaders = {
                'Content-Type': 'application/json',
                ...headers,
            };
            const requestInit = {
                method,
                headers: requestHeaders,
                signal: controller.signal,
            };
            if (body !== undefined) {
                requestInit.body = typeof body === 'string' ? body : JSON.stringify(body);
            }
            const response = await fetch(url, requestInit);
            const text = await response.text();
            let data;
            try {
                data = JSON.parse(text);
            }
            catch {
                // Response might not be JSON
                data = text;
            }
            return {
                status: response.status,
                ok: response.ok,
                headers: response.headers,
                data,
                text,
            };
        }
        finally {
            clearTimeout(timeoutId);
        }
    }
    /**
     * Make an HTTP POST request
     */
    async httpPost(url, body, headers) {
        return this.httpRequest({
            url,
            method: 'POST',
            headers,
            body,
        });
    }
    /**
     * Make an HTTP request and throw on non-2xx response
     */
    async httpRequestOrThrow(options) {
        const response = await this.httpRequest(options);
        if (!response.ok) {
            const errorMessage = this.extractErrorMessage(response);
            throw new Error(errorMessage);
        }
        return response;
    }
    /**
     * Extract error message from HTTP response
     */
    extractErrorMessage(response) {
        const { status, data, text } = response;
        // Try to extract error message from common response formats
        if (data && typeof data === 'object') {
            const errorObj = data;
            if (typeof errorObj.error === 'string') {
                return `HTTP ${status}: ${errorObj.error}`;
            }
            if (typeof errorObj.message === 'string') {
                return `HTTP ${status}: ${errorObj.message}`;
            }
            if (typeof errorObj.error_description === 'string') {
                return `HTTP ${status}: ${errorObj.error_description}`;
            }
        }
        // Fallback to status and truncated text
        const truncatedText = text.length > 200 ? text.slice(0, 200) + '...' : text;
        return `HTTP ${status}: ${truncatedText}`;
    }
    /**
     * Build default headers (can be overridden by subclasses)
     */
    getDefaultHeaders() {
        return {
            'Content-Type': 'application/json',
        };
    }
    /**
     * Merge headers with defaults
     */
    mergeHeaders(customHeaders) {
        return {
            ...this.getDefaultHeaders(),
            ...customHeaders,
        };
    }
}
//# sourceMappingURL=http-base.js.map