"use strict";
/**
 * Production transports for the ApprovalChannelDispatcher (W1.10).
 *
 * Provides concrete EmailSender + SmsSender implementations wired against
 * real production APIs:
 *   - Email: Resend (https://resend.com/docs/api-reference/emails/send-email)
 *   - SMS:   Twilio (https://www.twilio.com/docs/messaging/send-messages)
 *
 * Both adapters accept an injectable `transport` so they can be unit-tested
 * without hitting the network. In production the default transport uses
 * node:https directly with no external SDK dependency.
 *
 * @connexum/ai-governance  F-NEW-PRODUCT-APPROVAL-CHANNEL-EMAIL-SMS (production wiring)
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.nodeHttpsTransport = void 0;
exports.createResendEmailSender = createResendEmailSender;
exports.createTwilioSmsSender = createTwilioSmsSender;
const https = __importStar(require("node:https"));
const nodeHttpsTransport = (req) => new Promise((resolve, reject) => {
    const r = https.request({
        method: req.method,
        hostname: req.hostname,
        path: req.path,
        headers: req.headers,
    }, (res) => {
        const chunks = [];
        res.on('data', (c) => chunks.push(c));
        res.on('end', () => resolve({
            status: res.statusCode ?? 0,
            bodyText: Buffer.concat(chunks).toString('utf8'),
        }));
        res.on('error', reject);
    });
    r.on('error', reject);
    if (req.body !== undefined)
        r.write(req.body);
    r.end();
});
exports.nodeHttpsTransport = nodeHttpsTransport;
function createResendEmailSender(options) {
    if (!options.apiKey || options.apiKey.trim() === '') {
        throw new Error('createResendEmailSender: apiKey is required');
    }
    const fromAddress = options.fromAddress ?? 'governance@my-cc.io';
    const transport = options.transport ?? exports.nodeHttpsTransport;
    return {
        async send(params) {
            const body = JSON.stringify({
                from: fromAddress,
                to: [params.to],
                subject: params.subject,
                html: params.html,
                text: params.text,
            });
            try {
                const res = await transport({
                    method: 'POST',
                    hostname: 'api.resend.com',
                    path: '/emails',
                    headers: {
                        'content-type': 'application/json',
                        authorization: `Bearer ${options.apiKey}`,
                        'content-length': Buffer.byteLength(body).toString(),
                    },
                    body,
                });
                if (res.status >= 200 && res.status < 300) {
                    let messageId;
                    try {
                        const parsed = JSON.parse(res.bodyText);
                        messageId = parsed.id;
                    }
                    catch {
                        // Some upstreams return an empty body on success.
                    }
                    return { ok: true, messageId };
                }
                return {
                    ok: false,
                    error: `resend status=${res.status} body=${res.bodyText.slice(0, 256)}`,
                };
            }
            catch (err) {
                return { ok: false, error: `resend transport error: ${err.message}` };
            }
        },
    };
}
function createTwilioSmsSender(options) {
    if (!options.accountSid || !options.authToken || !options.from) {
        throw new Error('createTwilioSmsSender: accountSid, authToken, and from are required');
    }
    const transport = options.transport ?? exports.nodeHttpsTransport;
    const basicAuth = Buffer.from(`${options.accountSid}:${options.authToken}`).toString('base64');
    return {
        async send(params) {
            // Twilio expects application/x-www-form-urlencoded.
            const fromKey = options.from.startsWith('MG') ? 'MessagingServiceSid' : 'From';
            const formBody = new URLSearchParams({
                [fromKey]: options.from,
                To: params.to,
                Body: params.body,
            }).toString();
            try {
                const res = await transport({
                    method: 'POST',
                    hostname: 'api.twilio.com',
                    path: `/2010-04-01/Accounts/${encodeURIComponent(options.accountSid)}/Messages.json`,
                    headers: {
                        'content-type': 'application/x-www-form-urlencoded',
                        authorization: `Basic ${basicAuth}`,
                        'content-length': Buffer.byteLength(formBody).toString(),
                    },
                    body: formBody,
                });
                if (res.status >= 200 && res.status < 300) {
                    let messageId;
                    try {
                        const parsed = JSON.parse(res.bodyText);
                        messageId = parsed.sid;
                    }
                    catch {
                        // Tolerate non-JSON success bodies.
                    }
                    return { ok: true, messageId };
                }
                return {
                    ok: false,
                    error: `twilio status=${res.status} body=${res.bodyText.slice(0, 256)}`,
                };
            }
            catch (err) {
                return { ok: false, error: `twilio transport error: ${err.message}` };
            }
        },
    };
}
//# sourceMappingURL=approval-channel-adapters.js.map