import { Resource, ResourceKind } from "../resource.js";
import { createCloudflareApi } from "./api.js";
import { resolveEmailZoneId } from "./email-common.js";
export function isEmailCatchAll(resource) {
    return resource?.[ResourceKind] === "cloudflare::EmailCatchAll";
}
function validateCatchAllActions(actions) {
    for (const action of actions) {
        if (action.type === "drop") {
            continue;
        }
        if (!action.value?.length) {
            throw new Error(`EmailCatchAll action "${action.type}" requires at least one value.`);
        }
    }
}
/**
 * Configures a catch-all email routing rule that handles emails not matched by other rules.
 * This rule is processed last and typically matches all emails that haven't been handled.
 *
 * @example
 * ## Forward all unmatched emails
 *
 * Set up a catch-all rule to forward any unmatched emails to an admin address.
 *
 * ```ts
 * const catchAll = await EmailCatchAll("default-catchall", {
 *   zone: "example.com",
 *   enabled: true,
 *   actions: [
 *     {
 *       type: "forward",
 *       value: ["admin@company.com"]
 *     }
 *   ]
 * });
 * ```
 *
 * @example
 * ## Drop unmatched emails
 *
 * Configure catch-all to drop any emails that don't match specific rules.
 *
 * ```ts
 * const catchAll = await EmailCatchAll("drop-catchall", {
 *   zone: "example.com",
 *   enabled: true,
 *   actions: [
 *     {
 *       type: "drop"
 *     }
 *   ]
 * });
 * ```
 *
 * @example
 * ## Process with Worker
 *
 * Use a Worker to handle all unmatched emails for custom processing.
 *
 * ```ts
 * const catchAll = await EmailCatchAll("worker-catchall", {
 *   zone: "example.com",
 *   enabled: true,
 *   actions: [
 *     {
 *       type: "worker",
 *       value: ["email-processor"]
 *     }
 *   ]
 * });
 * ```
 */
export const EmailCatchAll = Resource("cloudflare::EmailCatchAll", async function (_id, props) {
    const api = await createCloudflareApi(props);
    const zoneId = await resolveEmailZoneId(api, props.zone);
    validateCatchAllActions(props.actions);
    if (this.phase === "delete") {
        // Disable the catch-all rule by setting enabled to false
        const disablePayload = {
            enabled: false,
            name: "Catch All",
            matchers: [{ type: "all" }],
            actions: [{ type: "drop" }],
        };
        const response = await api.put(`/zones/${zoneId}/email/routing/rules/catch_all`, disablePayload);
        if (!response.ok && response.status !== 404) {
            throw new Error(`Failed to disable catch-all rule: ${response.statusText}`);
        }
        return this.destroy();
    }
    // Get current catch-all rule state
    const _getResponse = await api.get(`/zones/${zoneId}/email/routing/rules/catch_all`);
    if (this.phase === "update" && this.output) {
        // Update the catch-all rule
        const updatePayload = {
            enabled: props.enabled ?? true,
            name: props.name || "Catch All",
            matchers: props.matchers || [{ type: "all" }],
            actions: props.actions,
        };
        const response = await api.put(`/zones/${zoneId}/email/routing/rules/catch_all`, updatePayload);
        if (!response.ok) {
            const errorBody = await response.text();
            throw new Error(`Failed to update catch-all rule: ${response.statusText}\nResponse: ${errorBody}`);
        }
        const result = (await response.json());
        return {
            zoneId,
            ruleId: result.result.id,
            enabled: result.result.enabled,
            name: result.result.name,
            matchers: result.result.matchers,
            actions: result.result.actions,
            tag: result.result.tag || undefined,
        };
    }
    // Create or update catch-all rule
    const catchAllPayload = {
        enabled: props.enabled ?? true,
        name: props.name || "Catch All",
        matchers: props.matchers || [{ type: "all" }],
        actions: props.actions,
    };
    const response = await api.put(`/zones/${zoneId}/email/routing/rules/catch_all`, catchAllPayload);
    if (!response.ok) {
        const errorBody = await response.text();
        throw new Error(`Failed to configure catch-all rule: ${response.statusText}\nResponse: ${errorBody}`);
    }
    const result = (await response.json());
    return {
        zoneId,
        ruleId: result.result.id,
        enabled: result.result.enabled,
        name: result.result.name,
        matchers: result.result.matchers,
        actions: result.result.actions,
        tag: result.result.tag || undefined,
    };
});
//# sourceMappingURL=email-catch-all.js.map