import { Resource } from "../resource.js";
import { handleApiError } from "./api-error.js";
import { createCloudflareApi, } from "./api.js";
import { findZoneForHostname } from "./zone.js";
/**
 * Cloudflare Ruleset manages rules within a specific phase's entrypoint ruleset.
 * This resource allows you to configure rules for various phases like rate limiting,
 * firewall, transforms, and more.
 *
 * @example
 * // Create a rate limiting ruleset
 * const rateLimits = await Ruleset("api-rate-limits", {
 *   zone: "example.com",
 *   phase: "http_ratelimit",
 *   rules: [
 *     {
 *       description: "API rate limit",
 *       expression: "(http.request.uri.path wildcard r\"/api/*\")",
 *       action: "block",
 *       ratelimit: {
 *         characteristics: ["ip.src"],
 *         period: 60,
 *         requests_per_period: 100,
 *         mitigation_timeout: 600
 *       }
 *     }
 *   ]
 * });
 *
 * @example
 * // Create a custom firewall ruleset
 * const firewall = await Ruleset("custom-firewall", {
 *   zone: myZone,
 *   phase: "http_request_firewall_custom",
 *   rules: [
 *     {
 *       description: "Block bad IPs",
 *       expression: "ip.src in {1.2.3.4 1.2.3.5}",
 *       action: "block"
 *     },
 *     {
 *       description: "Challenge suspicious requests",
 *       expression: "cf.threat_score > 50",
 *       action: "challenge"
 *     }
 *   ]
 * });
 *
 * @example
 * // Create a transform ruleset for request headers
 * const transforms = await Ruleset("header-transforms", {
 *   zone: "example.com",
 *   phase: "http_request_transform",
 *   rules: [
 *     {
 *       description: "Add custom header",
 *       expression: "true",
 *       action: "rewrite",
 *       action_parameters: {
 *         headers: {
 *           "X-Custom-Header": { value: "my-value" }
 *         }
 *       }
 *     }
 *   ]
 * });
 */
export const Ruleset = Resource("cloudflare::Ruleset", async function (id, props) {
    const api = await createCloudflareApi(props);
    // Default phase to http_ratelimit if not specified
    const phase = props.phase || "http_ratelimit";
    // Get zone ID from zone name
    const zoneId = typeof props.zone === "string"
        ? (await findZoneForHostname(api, props.zone)).zoneId
        : props.zone.id;
    if (this.phase === "delete") {
        // Overwrite entire entrypoint with empty rules
        await updateRuleset(api, zoneId, phase, { rules: [] });
        return this.destroy();
    }
    const rulesetName = props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
    // Overwrite entire entrypoint with only the provided rules
    const result = await updateRuleset(api, zoneId, phase, {
        rules: props.rules,
        name: rulesetName,
        ...(props.description && { description: props.description }),
    });
    // Transform response back to our format
    return {
        id: result.id,
        zoneId,
        phase: props.phase,
        name: result.name || props.name || `${phase} ruleset`,
        description: result.description || props.description,
        rules: result.rules ?? [],
        lastUpdated: result.last_updated,
        version: result.version,
    };
});
/**
 * Update a ruleset for a specific zone and phase
 * Ensures consistent error handling on non-2xx responses
 */
export async function updateRuleset(api, zoneId, 
/** Phase of the ruleset */
phase, body) {
    const response = await api.put(`/zones/${zoneId}/rulesets/phases/${phase}/entrypoint`, body);
    if (!response.ok) {
        await handleApiError(response, "updating", "ruleset", `${zoneId}/${phase}`);
    }
    const data = (await response.json());
    return data.result;
}
export async function getRuleset(api, zoneId, phase) {
    const response = await api.get(`/zones/${zoneId}/rulesets/phases/${phase}/entrypoint`);
    const data = (await response.json());
    return data.result;
}
//# sourceMappingURL=ruleset.js.map