use std::collections::BTreeMap;

use crank_core::{ExecutionConfig, Operation, OperationId, Protocol, Target, ToolDescription};
use crank_mapping::MappingSet;
use crank_schema::Schema;
use serde::{Deserialize, Serialize};
use serde_json::Value;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct RuntimeOperation {
    pub operation_id: OperationId,
    pub tool_name: String,
    pub protocol: Protocol,
    pub target: Target,
    pub input_schema: Schema,
    pub output_schema: Schema,
    pub input_mapping: MappingSet,
    pub output_mapping: MappingSet,
    pub execution_config: ExecutionConfig,
    pub tool_description: ToolDescription,
}

impl From<Operation<Schema, MappingSet>> for RuntimeOperation {
    fn from(value: Operation<Schema, MappingSet>) -> Self {
        Self {
            operation_id: value.id,
            tool_name: value.name,
            protocol: value.protocol,
            target: value.target,
            input_schema: value.input_schema,
            output_schema: value.output_schema,
            input_mapping: value.input_mapping,
            output_mapping: value.output_mapping,
            execution_config: value.execution_config,
            tool_description: value.tool_description,
        }
    }
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
pub struct PreparedRequest {
    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
    pub path_params: BTreeMap<String, String>,
    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
    pub query_params: BTreeMap<String, String>,
    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
    pub headers: BTreeMap<String, String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub grpc: Option<Value>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub variables: Option<Value>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub body: Option<Value>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct AdapterResponse {
    pub status_code: u16,
    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
    pub headers: BTreeMap<String, String>,
    pub body: Value,
    pub data: Value,
}
