// Bitbucket Data Center MCP server — generated by mcpify. Do not hand-edit.

use crate::auth::auth_manager::AuthManager;
use crate::auth::request_credentials::RequestCredentials;
use crate::core::config_schema::Config;
use crate::data::store::EndpointRecord;
use crate::services::api_client::ApiClient;
use crate::validation::validator::{validate_input, validate_output};

/// Validates arguments against the input schema, injects the active auth
/// strategy's credentials, executes the live HTTP request, and validates
/// the response against the output schema before returning it — PRD
/// §1.5's `call` pipeline (architecture.md's 4-step `call` pipeline),
/// protecting the calling agent from upstream API drift.
///
/// Takes an already-looked-up `EndpointRecord` rather than a `Connection`
/// and an `operation_id` to look up itself: `rusqlite::Connection` isn't
/// `Sync`, so a `&Connection` held across this function's `.await` points
/// (the HTTP call) would make the caller's future non-`Send` — a hard
/// requirement for `#[tool]` methods (Story R6). Callers look the
/// endpoint up (a synchronous, `Connection`-scoped step) before calling
/// this function, not inside it.
pub async fn call_operation(
    endpoint: &EndpointRecord,
    config: &Config,
    auth_manager: &mut AuthManager,
    operation_id: &str,
    args: serde_json::Value,
    request_override: Option<&RequestCredentials>,
) -> anyhow::Result<serde_json::Value> {
    validate_input(&config.api_version, operation_id, &args)?;

    let client = ApiClient::new(config.clone());
    let response = client
        .execute(endpoint, &args, auth_manager, request_override)
        .await?;

    validate_output(&config.api_version, operation_id, &response)?;
    Ok(response)
}
