use actix_web::HttpResponse;
use actix_web::http::StatusCode;
use serde_json::Value;
use serde_json::json;
use crate::api::gateway::contracts::GatewayOperationKind;
use athena_gateway::GatewayErrorEnvelope;
pub use athena_gateway::{
GATEWAY_ERROR_CODE_BACKEND_TEMPORARILY_UNAVAILABLE, GATEWAY_ERROR_CODE_BACKEND_UNAVAILABLE,
GATEWAY_ERROR_CODE_CLIENT_CATALOG_UNAVAILABLE, GATEWAY_ERROR_CODE_CLIENT_FROZEN,
GATEWAY_ERROR_CODE_CLIENT_INACTIVE, GATEWAY_ERROR_CODE_CLIENT_LOOKUP_FAILED,
GATEWAY_ERROR_CODE_D1_BACKEND_UNAVAILABLE, GATEWAY_ERROR_CODE_DEFERRED_QUERY_NOT_SUPPORTED,
GATEWAY_ERROR_CODE_DEFERRED_QUEUE_UNAVAILABLE, GATEWAY_ERROR_CODE_DELETE_EXECUTION_FAILED,
GATEWAY_ERROR_CODE_EMPTY_QUERY, GATEWAY_ERROR_CODE_FETCH_DATA_FAILED,
GATEWAY_ERROR_CODE_FETCH_DELEGATION_FAILED,
GATEWAY_ERROR_CODE_FETCH_RESPONSE_PROCESSING_FAILED,
GATEWAY_ERROR_CODE_INSERT_WINDOW_RESPONSE_CHANNEL_DROPPED, GATEWAY_ERROR_CODE_INTERNAL_ERROR,
GATEWAY_ERROR_CODE_INVALID_CLIENT, GATEWAY_ERROR_CODE_INVALID_CLIENT_METADATA,
GATEWAY_ERROR_CODE_INVALID_CONDITION_VALUE, GATEWAY_ERROR_CODE_INVALID_DELETE_PAYLOAD,
GATEWAY_ERROR_CODE_INVALID_DELETE_RESOURCE_ID_COLUMN,
GATEWAY_ERROR_CODE_INVALID_FETCH_CONDITION, GATEWAY_ERROR_CODE_INVALID_INSERT_PAYLOAD,
GATEWAY_ERROR_CODE_INVALID_POST_PROCESSING_CONFIGURATION,
GATEWAY_ERROR_CODE_INVALID_QUERY_PAYLOAD,
GATEWAY_ERROR_CODE_INVALID_RELATION_SELECT_COMPATIBILITY_QUERY,
GATEWAY_ERROR_CODE_INVALID_ROUTE_TARGET, GATEWAY_ERROR_CODE_INVALID_SCHEMA_NAME,
GATEWAY_ERROR_CODE_INVALID_SCHEMA_TABLE_SELECTOR,
GATEWAY_ERROR_CODE_INVALID_STRUCTURED_SELECT_REQUEST,
GATEWAY_ERROR_CODE_MALFORMED_JSON_PAYLOAD, GATEWAY_ERROR_CODE_MISSING_CLIENT_HEADER,
GATEWAY_ERROR_CODE_MISSING_CONDITIONS, GATEWAY_ERROR_CODE_MISSING_EQ_COLUMN_PARAMETER,
GATEWAY_ERROR_CODE_MISSING_EQ_VALUE_PARAMETER, GATEWAY_ERROR_CODE_MISSING_ORGANIZATION_HEADER,
GATEWAY_ERROR_CODE_MISSING_REQUEST_BODY, GATEWAY_ERROR_CODE_MISSING_RESOURCE_ID,
GATEWAY_ERROR_CODE_MISSING_TABLE_NAME, GATEWAY_ERROR_CODE_MISSING_UPDATE_PAYLOAD,
GATEWAY_ERROR_CODE_MISSING_VIEW_PARAMETER, GATEWAY_ERROR_CODE_OUTBOUND_REQUEST_RATE_LIMITED,
GATEWAY_ERROR_CODE_QUERY_BACKEND_UNAVAILABLE, GATEWAY_ERROR_CODE_QUERY_EXECUTION_FAILED,
GATEWAY_ERROR_CODE_QUERY_SQL_EXECUTION_FAILED, GATEWAY_ERROR_CODE_ROUTE_TARGET_LOOP_DETECTED,
GATEWAY_ERROR_CODE_ROUTE_TARGET_RESPONSE_UNAVAILABLE,
GATEWAY_ERROR_CODE_ROUTE_TARGET_UNAVAILABLE, GATEWAY_ERROR_CODE_SCYLLA_BACKEND_UNAVAILABLE,
GATEWAY_ERROR_CODE_SERVICE_UNAVAILABLE, GATEWAY_ERROR_CODE_SUPABASE_CLIENT_RESOLUTION_FAILED,
GATEWAY_ERROR_CODE_UNSUPPORTED_GATEWAY_FETCH_SHAPE, GATEWAY_ERROR_CODE_UNSUPPORTED_SCHEMA_NAME,
GATEWAY_ERROR_CODE_VALIDATION_FAILED,
};
pub fn gateway_error_with_details(
status: StatusCode,
code: impl Into<String>,
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
details: Option<Value>,
) -> HttpResponse {
HttpResponse::build(status).json(GatewayErrorEnvelope::new(
code, operation, message, error, details,
))
}
pub fn gateway_bad_request_with_details(
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
details: Option<Value>,
) -> HttpResponse {
gateway_error_with_details(
StatusCode::BAD_REQUEST,
GATEWAY_ERROR_CODE_VALIDATION_FAILED,
operation,
message,
error,
details,
)
}
pub fn gateway_bad_request_with_code_and_details(
code: impl Into<String>,
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
details: Option<Value>,
) -> HttpResponse {
gateway_error_with_details(
StatusCode::BAD_REQUEST,
code,
operation,
message,
error,
details,
)
}
pub fn gateway_bad_request_with_code(
code: impl Into<String>,
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
) -> HttpResponse {
gateway_bad_request_with_code_and_details(code, operation, message, error, None)
}
pub fn gateway_bad_request(
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
) -> HttpResponse {
gateway_bad_request_with_details(operation, message, error, None)
}
pub fn gateway_internal_error_with_code(
code: impl Into<String>,
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
) -> HttpResponse {
gateway_error_with_details(
StatusCode::INTERNAL_SERVER_ERROR,
code,
operation,
message,
error,
None,
)
}
pub fn gateway_internal_error(
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
) -> HttpResponse {
gateway_error_with_details(
StatusCode::INTERNAL_SERVER_ERROR,
GATEWAY_ERROR_CODE_INTERNAL_ERROR,
operation,
message,
error,
None,
)
}
pub fn gateway_service_unavailable_with_code(
code: impl Into<String>,
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
) -> HttpResponse {
gateway_error_with_details(
StatusCode::SERVICE_UNAVAILABLE,
code,
operation,
message,
error,
None,
)
}
pub fn gateway_service_unavailable(
operation: GatewayOperationKind,
message: impl Into<String>,
error: impl Into<String>,
) -> HttpResponse {
gateway_error_with_details(
StatusCode::SERVICE_UNAVAILABLE,
GATEWAY_ERROR_CODE_SERVICE_UNAVAILABLE,
operation,
message,
error,
None,
)
}
pub fn missing_client_header_response(operation: GatewayOperationKind) -> HttpResponse {
gateway_bad_request_with_code_and_details(
GATEWAY_ERROR_CODE_MISSING_CLIENT_HEADER,
operation,
"Missing required header",
"X-Athena-Client header or x-pg-uri is required and cannot be empty",
Some(json!({
"missing_header": "X-Athena-Client or x-pg-uri"
})),
)
}