import { Resource } from "../resource.js";
import { handleApiError } from "./api-error.js";
import { createCloudflareApi, } from "./api.js";
/**
 * Cloudflare API Gateway Operation manages individual API endpoints that can be
 * monitored, secured, and configured through Cloudflare's API Shield.
 *
 * Operations are the building blocks for API management, representing specific
 * HTTP method + endpoint + host combinations that your API exposes.
 *
 * @example
 * ## Basic API operation
 *
 * Create a simple GET endpoint for user retrieval
 *
 * const getUserOp = await APIGatewayOperation("get-users", {
 *   zone: myZone,
 *   endpoint: "/users",
 *   host: "api.example.com",
 *   method: "GET"
 * });
 *
 * @example
 * ## API operation with path parameters
 *
 * Create an operation that includes path variables
 *
 * const getUserByIdOp = await APIGatewayOperation("get-user-by-id", {
 *   zone: "api.example.com",
 *   endpoint: "/users/{id}",
 *   host: "api.example.com",
 *   method: "GET"
 * });
 *
 * @example
 * ## RESTful CRUD operations
 *
 * Create a complete set of CRUD operations for a resource
 *
 * const createUserOp = await APIGatewayOperation("create-user", {
 *   zone: myZone,
 *   endpoint: "/users",
 *   host: "api.example.com",
 *   method: "POST"
 * });
 *
 * const updateUserOp = await APIGatewayOperation("update-user", {
 *   zone: myZone,
 *   endpoint: "/users/{id}",
 *   host: "api.example.com",
 *   method: "PUT"
 * });
 *
 * const deleteUserOp = await APIGatewayOperation("delete-user", {
 *   zone: myZone,
 *   endpoint: "/users/{id}",
 *   host: "api.example.com",
 *   method: "DELETE"
 * });
 *
 * @see https://developers.cloudflare.com/api/resources/api_gateway/subresources/operations/
 * @see https://developers.cloudflare.com/api-shield/management-and-monitoring/endpoint-management/
 */
export const APIGatewayOperation = Resource("cloudflare::APIGatewayOperation", async function (_id, props) {
    const api = await createCloudflareApi(props);
    // Resolve zone ID and name
    const zoneId = typeof props.zone === "string" ? props.zone : props.zone.id;
    const zoneName = typeof props.zone === "string" ? props.zone : props.zone.name;
    if (this.phase === "delete") {
        if (this.output?.operationId) {
            await deleteOperation(api, zoneId, this.output.operationId);
        }
        return this.destroy();
    }
    let operationId;
    if (this.phase === "update") {
        if (props.endpoint !== this.output?.endpoint ||
            props.host !== this.output?.host ||
            props.method !== this.output?.method) {
            // delete and then re-create (cloudflare doesn't allow updating these properties)
            this.replace(true);
        }
        if (props.mitigation !== this.output?.action) {
            // we can update the mitigation action
            await updateOperationSettings(api, zoneId, this.output.operationId, {
                mitigation_action: props.mitigation ?? null,
            });
        }
        operationId = this.output.operationId;
    }
    else {
        const operation = await createOperation(api, zoneId, props);
        operationId = operation.operation_id;
        if (props.mitigation) {
            await updateOperationSettings(api, zoneId, operationId, {
                mitigation_action: props.mitigation ?? "none",
            });
        }
    }
    return {
        zoneId,
        zoneName,
        operationId,
        endpoint: props.endpoint,
        host: props.host,
        method: props.method.toUpperCase(),
        action: props.mitigation ?? null,
    };
});
async function createOperation(api, zoneId, props) {
    // Create the operation
    const response = await api.post(`/zones/${zoneId}/api_gateway/operations/item`, {
        endpoint: props.endpoint,
        host: props.host,
        method: props.method.toUpperCase(),
    });
    if (!response.ok) {
        await handleApiError(response, "creating", "operation", `${props.method} ${props.endpoint}`);
    }
    const data = (await response.json());
    return data.result;
}
async function deleteOperation(api, zoneId, operationId) {
    const deleteResponse = await api.delete(`/zones/${zoneId}/api_gateway/operations/${operationId}`);
    if (!deleteResponse.ok && deleteResponse.status !== 404) {
        await handleApiError(deleteResponse, "deleting", "operation", operationId);
    }
}
/**
 * Update validation settings for a specific operation
 */
async function updateOperationSettings(api, zoneId, operationId, params) {
    const response = await api.put(`/zones/${zoneId}/schema_validation/settings/operations/${operationId}`, params);
    if (!response.ok) {
        await handleApiError(response, "updating", "operation settings", operationId);
    }
}
export async function getOperations(api, zoneId) {
    const response = await api.get(`/zones/${zoneId}/api_gateway/operations`);
    if (!response.ok) {
        await handleApiError(response, "getting", "operations");
    }
    return (await response.json()).result;
}
export async function getOperationSchemaValidationSetting(api, zoneId, operationId) {
    const response = await api.get(`/zones/${zoneId}/schema_validation/settings/operations/${operationId}`);
    if (!response.ok) {
        await handleApiError(response, "getting", "operation mitigation status", operationId);
    }
    const data = (await response.json());
    return data.result;
}
//# sourceMappingURL=api-gateway-operation.js.map