//! OpenAPI documentation generation.
//!
//! This module generates OpenAPI 3.1 specifications for all gateway endpoints
//! using utoipa.

use utoipa::openapi::security::{ApiKey, ApiKeyValue, HttpAuthScheme, HttpBuilder, SecurityScheme};
use utoipa::{Modify, OpenApi};

use crate::response::{HealthResponse, HealthStatus, PaginationMeta, ServiceHealth};

/// OpenAPI documentation for the Synor Gateway API.
#[derive(OpenApi)]
#[openapi(
    info(
        title = "Synor Gateway API",
        version = "1.0.0",
        description = "Unified REST API gateway for all Synor blockchain services.\n\nProvides access to wallet management, blockchain RPC, decentralized storage, DEX trading, IBC cross-chain operations, zero-knowledge proofs, and smart contract compilation.",
        contact(
            name = "Synor Team",
            email = "api@synor.io",
            url = "https://synor.io"
        ),
        license(
            name = "MIT OR Apache-2.0",
            url = "https://github.com/synortech/synor/blob/main/LICENSE"
        )
    ),
    servers(
        (url = "https://api.synor.io/v1", description = "Production API"),
        (url = "https://testnet.api.synor.io/v1", description = "Testnet API"),
        (url = "http://localhost:8000/v1", description = "Local development")
    ),
    tags(
        (name = "Health", description = "Service health and status endpoints"),
        (name = "Wallet", description = "Wallet management and key operations"),
        (name = "RPC", description = "Blockchain RPC and chain state"),
        (name = "Storage", description = "Decentralized storage operations"),
        (name = "DEX", description = "Decentralized exchange trading"),
        (name = "IBC", description = "Inter-Blockchain Communication"),
        (name = "ZK", description = "Zero-knowledge proof operations"),
        (name = "Compiler", description = "Smart contract compilation and analysis")
    ),
    components(
        schemas(
            // Response types
            HealthResponse,
            HealthStatus,
            ServiceHealth,
            PaginationMeta,
        )
    ),
    modifiers(&SecurityAddon)
)]
pub struct ApiDoc;

/// Security scheme modifier for OpenAPI documentation.
struct SecurityAddon;

impl Modify for SecurityAddon {
    fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
        if let Some(components) = openapi.components.as_mut() {
            components.add_security_scheme(
                "api_key",
                SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new("X-API-Key"))),
            );
            components.add_security_scheme(
                "bearer_auth",
                SecurityScheme::Http(
                    HttpBuilder::new()
                        .scheme(HttpAuthScheme::Bearer)
                        .bearer_format("JWT")
                        .build(),
                ),
            );
        }
    }
}

/// Generate the OpenAPI JSON specification.
pub fn generate_openapi_json() -> String {
    ApiDoc::openapi().to_json().unwrap_or_else(|e| {
        tracing::error!("Failed to generate OpenAPI JSON: {}", e);
        "{}".to_string()
    })
}

/// Generate the OpenAPI YAML specification.
pub fn generate_openapi_yaml() -> String {
    // utoipa 4.x doesn't have to_yaml, use JSON for now
    generate_openapi_json()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_openapi_generation() {
        let json = generate_openapi_json();
        assert!(!json.is_empty());
        assert!(json.contains("Synor Gateway API"));
    }
}
