use crank_adapter_graphql::GraphqlAdapterError;
use crank_adapter_grpc::GrpcAdapterError;
use crank_adapter_rest::RestAdapterError;
use crank_adapter_soap::SoapAdapterError;
use crank_adapter_websocket::WebsocketAdapterError;
use crank_core::{ExecutionMode, Protocol};
use crank_mapping::MappingError;
use crank_schema::SchemaError;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum RuntimeError {
    #[error(transparent)]
    Schema(#[from] SchemaError),
    #[error(transparent)]
    Mapping(#[from] MappingError),
    #[error(transparent)]
    GraphqlAdapter(#[from] GraphqlAdapterError),
    #[error(transparent)]
    GrpcAdapter(#[from] GrpcAdapterError),
    #[error(transparent)]
    RestAdapter(#[from] RestAdapterError),
    #[error(transparent)]
    SoapAdapter(#[from] SoapAdapterError),
    #[error(transparent)]
    WebsocketAdapter(#[from] WebsocketAdapterError),
    #[error("protocol {protocol:?} is not supported by runtime")]
    UnsupportedProtocol { protocol: Protocol },
    #[error("operation {operation_id} does not define streaming config")]
    MissingStreamingConfig { operation_id: String },
    #[error("operation {operation_id} does not support requested execution mode {mode:?}")]
    UnsupportedExecutionMode {
        operation_id: String,
        mode: ExecutionMode,
    },
    #[error("runtime concurrency limit exceeded for {kind} executions (limit {limit})")]
    ConcurrencyLimitExceeded { kind: &'static str, limit: usize },
    #[error("invalid prepared request at {field}: {reason}")]
    InvalidPreparedRequest { field: String, reason: String },
    #[error("invalid streaming payload at {field}: {reason}")]
    InvalidStreamingPayload { field: String, reason: String },
    #[error("auth profile {auth_profile_id} was not found")]
    MissingAuthProfile { auth_profile_id: String },
    #[error("secret {secret_id} was not found")]
    MissingSecret { secret_id: String },
    #[error("secret {secret_id} does not have current version {version}")]
    MissingSecretVersion { secret_id: String, version: u32 },
    #[error("invalid secret payload for {secret_id}: {reason}")]
    InvalidAuthSecretValue { secret_id: String, reason: String },
    #[error("secret crypto error during {operation}: {details}")]
    SecretCrypto {
        operation: &'static str,
        details: String,
    },
}
