// File: crates/smithy-generator/build.rs

// crates/smithy-generator/build.rs

use std::{collections::HashSet, fs, path::Path};

use regex::Regex;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    run_build()
}

fn run_build() -> Result<(), Box<dyn std::error::Error>> {
    let workspace_root = get_workspace_root()?;

    // Detect enabled features for this build
    let enabled_features = detect_enabled_features();

    // Create feature resolver to map smithy-generator features to dependency features
    let feature_resolver = FeatureResolver::new(&enabled_features);

    let mut smithy_models = Vec::new();

    // Scan all crates in the workspace for SmithyModel derives
    let crates_dir = workspace_root.join("crates");
    if let Ok(entries) = fs::read_dir(&crates_dir) {
        for entry in entries.flatten() {
            if entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) {
                let crate_path = entry.path();
                let crate_name = match crate_path.file_name() {
                    Some(name) => name.to_string_lossy(),
                    None => {
                        continue;
                    }
                };

                // Skip the smithy crate itself to avoid self-dependency
                if crate_name == "smithy"
                    || crate_name == "smithy-core"
                    || crate_name == "smithy-generator"
                {
                    continue;
                }

                // Check if this crate should be scanned based on enabled features
                if feature_resolver.should_scan_crate(&crate_name) {
                    let _ = scan_crate_for_smithy_models(
                        &crate_path,
                        &crate_name,
                        &mut smithy_models,
                        &feature_resolver,
                    );
                }
            }
        }
    }

    // Generate the registry file
    generate_model_registry(&smithy_models)?;

    Ok(())
}

/// Detects which features are enabled for the current build
fn detect_enabled_features() -> HashSet<String> {
    let mut features = HashSet::new();

    // Check all CARGO_FEATURE_* environment variables
    for (key, value) in std::env::vars() {
        if key.starts_with("CARGO_FEATURE_") && value == "1" {
            if let Some(feature_suffix) = key.strip_prefix("CARGO_FEATURE_") {
                let feature_name = feature_suffix.to_lowercase().replace('_', "-");
                features.insert(feature_name);
            }
        }
    }

    // Always include default features if none are explicitly enabled
    // Note: We should be more careful about default feature assumptions
    if features.is_empty() {
        features.insert("v1".to_string());
    }

    features
}

/// Resolves feature dependencies between smithy-generator and its dependencies
struct FeatureResolver {
    enabled_features: HashSet<String>,
    crate_feature_cache: std::collections::HashMap<String, HashSet<String>>,
}

impl FeatureResolver {
    fn new(enabled_features: &HashSet<String>) -> Self {
        let mut resolver = Self {
            enabled_features: enabled_features.clone(),
            crate_feature_cache: std::collections::HashMap::new(),
        };

        // Pre-compute feature mappings for known crates
        resolver.initialize_feature_mappings();
        resolver
    }

    fn initialize_feature_mappings(&mut self) {
        // Initialize feature mappings for each known crate
        for crate_name in &["api_models", "common_utils", "common_types", "common_enums"] {
            let features = self.compute_crate_features(crate_name);
            self.crate_feature_cache
                .insert(crate_name.to_string(), features);
        }
    }

    /// Determines if a crate should be scanned based on enabled features
    fn should_scan_crate(&self, crate_name: &str) -> bool {
        match crate_name {
            "api_models" => {
                // api_models is a core crate that should always be scanned
                // The feature gates within the crate will determine what's available
                true
            }
            "common_utils" => {
                // common_utils is a core utility crate, always scan it
                true
            }
            "common_types" => {
                // common_types should be scanned if any version features are enabled
                self.enabled_features.contains("v1") || self.enabled_features.contains("v2")
            }
            "common_enums" => {
                // common_enums is used by most other crates, always scan it
                true
            }
            "router_derive" => {
                // Proc macro crate, not relevant for SmithyModel scanning
                false
            }
            "external_services" | "storage_impl" | "router" => {
                // These are application crates, may contain models but less likely
                // Include them but with lower priority
                true
            }
            _ => {
                // For unknown crates, include them by default to be safe
                true
            }
        }
    }

    /// Determines which features are enabled for a dependency crate
    fn get_enabled_crate_features(&self, crate_name: &str) -> HashSet<String> {
        // Use cached result if available
        if let Some(cached_features) = self.crate_feature_cache.get(crate_name) {
            return cached_features.clone();
        }

        // Compute features for unknown crates
        self.compute_crate_features(crate_name)
    }

    fn compute_crate_features(&self, crate_name: &str) -> HashSet<String> {
        let mut crate_features = HashSet::new();

        match crate_name {
            "api_models" => {
                // api_models has v1 and v2 features that directly map to smithy-generator features
                if self.enabled_features.contains("v1") {
                    crate_features.insert("v1".to_string());
                }
                if self.enabled_features.contains("v2") {
                    crate_features.insert("v2".to_string());
                }

                // api_models also has some derived features
                for feature in &self.enabled_features {
                    match feature.as_str() {
                        "frm" | "payouts" | "disputes" | "routing" => {
                            crate_features.insert(feature.clone());
                        }
                        _ => {}
                    }
                }
            }
            "common_utils" => {
                // common_utils features typically map directly
                if self.enabled_features.contains("v1") {
                    crate_features.insert("v1".to_string());
                }
                if self.enabled_features.contains("v2") {
                    crate_features.insert("v2".to_string());
                }
            }
            "common_types" => {
                // common_types has payment-related features
                if self.enabled_features.contains("v2") {
                    crate_features.insert("v2".to_string());
                }
                // Some features are version-independent
                for feature in &self.enabled_features {
                    match feature.as_str() {
                        "frm" | "payouts" | "disputes" => {
                            crate_features.insert(feature.clone());
                        }
                        _ => {}
                    }
                }
            }
            "common_enums" => {
                // common_enums typically doesn't have version-specific features
                // but may have functional features
                for feature in &self.enabled_features {
                    match feature.as_str() {
                        "frm" | "payouts" | "disputes" | "routing" => {
                            crate_features.insert(feature.clone());
                        }
                        _ => {}
                    }
                }
            }
            _ => {
                // For unknown crates, be conservative and only pass through
                // features that are commonly used
                for feature in &self.enabled_features {
                    match feature.as_str() {
                        "v1" | "v2" => {
                            crate_features.insert(feature.clone());
                        }
                        _ => {}
                    }
                }
            }
        }

        crate_features
    }
}

fn get_workspace_root() -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
    let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")
        .map_err(|_| "CARGO_MANIFEST_DIR environment variable not set")?;

    let manifest_path = Path::new(&manifest_dir);

    let parent1 = manifest_path
        .parent()
        .ok_or("Cannot get parent directory of CARGO_MANIFEST_DIR")?;

    let workspace_root = parent1
        .parent()
        .ok_or("Cannot get workspace root directory")?;

    Ok(workspace_root.to_path_buf())
}

fn scan_crate_for_smithy_models(
    crate_path: &Path,
    crate_name: &str,
    models: &mut Vec<SmithyModelInfo>,
    feature_resolver: &FeatureResolver,
) -> Result<(), Box<dyn std::error::Error>> {
    let src_path = crate_path.join("src");
    if !src_path.exists() {
        return Ok(());
    }

    let _enabled_features = feature_resolver.get_enabled_crate_features(crate_name);

    scan_directory(&src_path, crate_name, "", models, feature_resolver)?;
    Ok(())
}

fn scan_directory(
    dir: &Path,
    crate_name: &str,
    module_path: &str,
    models: &mut Vec<SmithyModelInfo>,
    feature_resolver: &FeatureResolver,
) -> Result<(), Box<dyn std::error::Error>> {
    if let Ok(entries) = fs::read_dir(dir) {
        for entry in entries.flatten() {
            let path = entry.path();
            if path.is_dir() {
                let dir_name = match path.file_name() {
                    Some(name) => name.to_string_lossy(),
                    None => {
                        continue;
                    }
                };
                let new_module_path = if module_path.is_empty() {
                    dir_name.to_string()
                } else {
                    format!("{}::{}", module_path, dir_name)
                };
                scan_directory(
                    &path,
                    crate_name,
                    &new_module_path,
                    models,
                    feature_resolver,
                )?;
            } else if path.extension().map(|ext| ext == "rs").unwrap_or(false) {
                let _ = scan_rust_file(&path, crate_name, module_path, models, feature_resolver);
            }
        }
    }
    Ok(())
}

fn scan_rust_file(
    file_path: &Path,
    crate_name: &str,
    module_path: &str,
    models: &mut Vec<SmithyModelInfo>,
    feature_resolver: &FeatureResolver,
) -> Result<(), Box<dyn std::error::Error>> {
    if let Ok(content) = fs::read_to_string(file_path) {
        // More precise regex that captures cfg attributes, derive, and struct/enum declarations
        // This captures cfg attributes that may be separated from derive by comments/other attributes
        let re = Regex::new(r"(?ms)((?:#\[cfg\([^\]]*\)\]\s*)*)((?:///[^\r\n]*\s*|#\[[^\]]*\]\s*)*)(#\[derive\([^)]*\bSmithyModel\b[^)]*\)\])\s*(?:(?:#\[[^\]]*\]\s*)|(?://[^\r\n]*\s*)|(?:///[^\r\n]*\s*)|(?:/\*.*?\*/\s*))*(?:pub\s+)?(?:struct|enum)\s+([A-Z][A-Za-z0-9_]*)\s*[<\{\(]")
            .map_err(|e| format!("Failed to compile regex: {}", e))?;

        for captures in re.captures_iter(&content) {
            let cfg_attrs = captures.get(1).map(|m| m.as_str()).unwrap_or("");
            let derive_attr = captures.get(3).map(|m| m.as_str()).unwrap_or("");
            let item_name = match captures.get(4) {
                Some(capture) => capture.as_str(),
                None => {
                    continue;
                }
            };

            // Verify this is actually a SmithyModel derive by checking the derive attribute more precisely
            if !derive_attr.contains("SmithyModel") {
                continue;
            }

            // For items with the same name but different feature gates (like FeatureMetadata),
            // we need to ensure we only include the version that actually has SmithyModel
            // under the current feature configuration
            let enabled_features = feature_resolver.get_enabled_crate_features(crate_name);

            // Special handling for items that have multiple definitions with different derives
            if item_name == "FeatureMetadata" {
                // FeatureMetadata only has SmithyModel in v1 version
                if !enabled_features.contains("v1") {
                    continue;
                }
            }

            // Check if this item is available under current feature gates
            if is_item_available_for_features(cfg_attrs, crate_name, feature_resolver) {
                // Validate that the item name is a valid Rust identifier
                if is_valid_rust_identifier(item_name) {
                    let full_module_path = create_module_path(file_path, crate_name, module_path)?;

                    models.push(SmithyModelInfo {
                        struct_name: item_name.to_string(),
                        module_path: full_module_path,
                        cfg_attrs: cfg_attrs.to_string(),
                    });
                }
            }
        }
    }
    Ok(())
}

/// Checks if an item is available under the current feature configuration
fn is_item_available_for_features(
    cfg_attrs: &str,
    crate_name: &str,
    feature_resolver: &FeatureResolver,
) -> bool {
    if cfg_attrs.trim().is_empty() {
        // No feature gates, item is always available
        return true;
    }

    let enabled_features = feature_resolver.get_enabled_crate_features(crate_name);

    // Parse each cfg attribute line
    let cfg_lines: Vec<&str> = cfg_attrs
        .lines()
        .map(|line| line.trim())
        .filter(|line| !line.is_empty() && line.starts_with("#[cfg("))
        .collect();

    // If no cfg attributes found, item is available
    if cfg_lines.is_empty() {
        return true;
    }

    // All cfg attributes must be satisfied (AND logic between different cfg attributes)
    for cfg_line in cfg_lines {
        if !evaluate_cfg_condition(cfg_line, &enabled_features) {
            return false;
        }
    }

    true
}

/// Evaluates a single cfg condition
fn evaluate_cfg_condition(cfg_line: &str, enabled_features: &HashSet<String>) -> bool {
    // Simple feature check: #[cfg(feature = "v1")]
    if let Some(captures) = Regex::new(r#"#\[cfg\(feature\s*=\s*"([^"]+)"\)\]"#)
        .ok()
        .and_then(|re| re.captures(cfg_line))
    {
        if let Some(feature_match) = captures.get(1) {
            let feature_name = feature_match.as_str();
            return enabled_features.contains(feature_name);
        }
    }

    // any() function: #[cfg(any(feature = "v1", feature = "v2"))]
    if let Some(captures) = Regex::new(r#"#\[cfg\(any\(([^)]+)\)\)\]"#)
        .ok()
        .and_then(|re| re.captures(cfg_line))
    {
        if let Some(any_content) = captures.get(1) {
            return evaluate_any_condition(any_content.as_str(), enabled_features);
        }
    }

    // all() function: #[cfg(all(feature = "v1", not(feature = "v2")))]
    if let Some(captures) = Regex::new(r#"#\[cfg\(all\(([^)]+)\)\)\]"#)
        .ok()
        .and_then(|re| re.captures(cfg_line))
    {
        if let Some(all_content) = captures.get(1) {
            return evaluate_all_condition(all_content.as_str(), enabled_features);
        }
    }

    // not() function: #[cfg(not(feature = "v1"))]
    if let Some(captures) = Regex::new(r#"#\[cfg\(not\(([^)]+)\)\)\]"#)
        .ok()
        .and_then(|re| re.captures(cfg_line))
    {
        if let Some(not_content) = captures.get(1) {
            return !evaluate_simple_feature_condition(not_content.as_str(), enabled_features);
        }
    }

    // If we can't parse the cfg condition, assume it's available to avoid false negatives
    true
}

/// Evaluates any() condition - returns true if any condition is met
fn evaluate_any_condition(condition: &str, enabled_features: &HashSet<String>) -> bool {
    let parts: Vec<&str> = condition.split(',').map(|s| s.trim()).collect();

    for part in parts {
        if evaluate_simple_feature_condition(part, enabled_features) {
            return true;
        }
    }

    false
}

/// Evaluates all() condition - returns true if all conditions are met
fn evaluate_all_condition(condition: &str, enabled_features: &HashSet<String>) -> bool {
    let parts: Vec<&str> = condition.split(',').map(|s| s.trim()).collect();

    for part in parts {
        if part.starts_with("not(") && part.ends_with(')') {
            let inner = &part[4..part.len() - 1];
            if evaluate_simple_feature_condition(inner, enabled_features) {
                return false; // not() condition failed
            }
        } else if !evaluate_simple_feature_condition(part, enabled_features) {
            return false;
        }
    }

    true
}

/// Evaluates a simple feature condition like 'feature = "v1"'
fn evaluate_simple_feature_condition(condition: &str, enabled_features: &HashSet<String>) -> bool {
    if let Some(captures) = Regex::new(r#"feature\s*=\s*"([^"]+)""#)
        .ok()
        .and_then(|re| re.captures(condition))
    {
        if let Some(feature_match) = captures.get(1) {
            let feature_name = feature_match.as_str();
            return enabled_features.contains(feature_name);
        }
    }

    // If we can't parse it, assume it's false for safety
    false
}

fn is_valid_rust_identifier(name: &str) -> bool {
    if name.is_empty() {
        return false;
    }

    // Rust identifiers must start with a letter or underscore
    let first_char = match name.chars().next() {
        Some(ch) => ch,
        None => return false, // This shouldn't happen since we checked is_empty above, but being safe
    };
    if !first_char.is_ascii_alphabetic() && first_char != '_' {
        return false;
    }

    // Must not be a Rust keyword
    let keywords = [
        "as", "break", "const", "continue", "crate", "else", "enum", "extern", "false", "fn",
        "for", "if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", "ref",
        "return", "self", "Self", "static", "struct", "super", "trait", "true", "type", "unsafe",
        "use", "where", "while", "async", "await", "dyn", "is", "abstract", "become", "box", "do",
        "final", "macro", "override", "priv", "typeof", "unsized", "virtual", "yield", "try",
    ];

    if keywords.contains(&name) {
        return false;
    }

    // All other characters must be alphanumeric or underscore
    name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')
}

fn create_module_path(
    file_path: &Path,
    crate_name: &str,
    module_path: &str,
) -> Result<String, Box<dyn std::error::Error>> {
    let file_name = file_path
        .file_stem()
        .and_then(|s| s.to_str())
        .ok_or_else(|| {
            format!(
                "Cannot extract file name from path: {}",
                file_path.display()
            )
        })?;

    let crate_name_normalized = crate_name.replace('-', "_");

    let result = if file_name == "lib" || file_name == "mod" {
        if module_path.is_empty() {
            crate_name_normalized
        } else {
            format!("{}::{}", crate_name_normalized, module_path)
        }
    } else if module_path.is_empty() {
        format!("{}::{}", crate_name_normalized, file_name)
    } else {
        format!("{}::{}::{}", crate_name_normalized, module_path, file_name)
    };

    Ok(result)
}

#[derive(Debug)]
struct SmithyModelInfo {
    struct_name: String,
    module_path: String,
    cfg_attrs: String,
}

fn generate_model_registry(models: &[SmithyModelInfo]) -> Result<(), Box<dyn std::error::Error>> {
    let out_dir = std::env::var("OUT_DIR").map_err(|_| "OUT_DIR environment variable not set")?;
    let registry_path = Path::new(&out_dir).join("model_registry.rs");

    let mut content = String::new();
    content.push_str("// Auto-generated model registry\n");
    content.push_str("// DO NOT EDIT - This file is generated by build.rs\n\n");

    if !models.is_empty() {
        content.push_str("use smithy_core::{SmithyModel, SmithyModelGenerator};\n\n");

        // Generate feature-gated imports
        for model in models {
            if !model.cfg_attrs.trim().is_empty() {
                // Add cfg attributes for conditional compilation
                content.push_str(&format!("{}\n", model.cfg_attrs.trim()));
            }
            content.push_str(&format!(
                "use {}::{};\n",
                model.module_path, model.struct_name
            ));
        }

        content.push_str("\npub fn discover_smithy_models() -> Vec<SmithyModel> {\n");
        content.push_str("    vec![\n");

        // Generate feature-gated model collection calls
        for model in models.iter() {
            if !model.cfg_attrs.trim().is_empty() {
                // Add cfg attributes for conditional compilation
                content.push_str(&format!("        {}\n", model.cfg_attrs.trim()));
            }
            content.push_str(&format!(
                "        {}::generate_smithy_model(),\n",
                model.struct_name
            ));
        }

        content.push_str("    ]\n");
        content.push_str("}\n");
    } else {
        // Generate empty function if no models found
        content.push_str("use smithy_core::SmithyModel;\n\n");
        content.push_str("pub fn discover_smithy_models() -> Vec<SmithyModel> {\n");
        content.push_str("    Vec::new()\n");
        content.push_str("}\n");
    }

    fs::write(&registry_path, content).map_err(|e| {
        format!(
            "Failed to write model registry to {}: {}",
            registry_path.display(),
            e
        )
    })?;

    Ok(())
}


// File: crates/smithy-generator/src/main.rs

// crates/smithy-generator/main.rs

use std::path::Path;

use router_env::logger;
use smithy_core::SmithyGenerator;

// Include the auto-generated model registry
include!(concat!(env!("OUT_DIR"), "/model_registry.rs"));

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut generator = SmithyGenerator::new();

    logger::info!("Discovering Smithy models from workspace...");

    // Automatically discover and add all models
    let models = discover_smithy_models();
    logger::info!("Found {} Smithy models", models.len());

    if models.is_empty() {
        logger::info!("No SmithyModel structs found. Make sure your structs:");
        logger::info!("  1. Derive SmithyModel: #[derive(SmithyModel)]");
        logger::info!("  2. Are in a crate that smithy can access");
        logger::info!("  3. Have the correct smithy attributes");
        return Ok(());
    }

    for model in models {
        logger::info!("  Processing namespace: {}", model.namespace);
        let shape_names: Vec<_> = model.shapes.keys().collect();
        logger::info!("    Shapes: {:?}", shape_names);
        generator.add_model(model);
    }

    logger::info!("Generating Smithy IDL files...");

    // Generate IDL files
    let output_dir = Path::new("smithy/models");
    let absolute_output_dir = std::env::current_dir()?.join(output_dir);

    logger::info!("Output directory: {}", absolute_output_dir.display());

    generator.generate_idl(output_dir)?;

    logger::info!("✅ Smithy models generated successfully!");
    logger::info!("Files written to: {}", absolute_output_dir.display());

    // List generated files
    if let Ok(entries) = std::fs::read_dir(output_dir) {
        logger::info!("Generated files:");
        for entry in entries.flatten() {
            if entry.file_type().map(|ft| ft.is_file()).unwrap_or(false) {
                logger::info!("  - {}", entry.file_name().to_string_lossy());
            }
        }
    }

    Ok(())
}


// File: crates/openapi/Cargo.toml

[package]
name = "openapi"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

[dependencies]
# Third party crates
serde_json = "1.0.140"
utoipa = { version = "4.2.3", features = ["preserve_order", "preserve_path_order", "time"] }

# First party crates
api_models = { version = "0.1.0", path = "../api_models", features = ["frm", "payouts", "openapi", "errors"] }
common_utils = { version = "0.1.0", path = "../common_utils", features = ["logs"] }
common_types = { version = "0.1.0", path = "../common_types" }
router_env = { version = "0.1.0", path = "../router_env" }
euclid = { version = "0.1.0", path = "../euclid" }

[features]
v2 = ["api_models/v2", "common_utils/v2", "api_models/tokenization_v2"]
v1 = ["api_models/v1", "common_utils/v1"]

[lints]
workspace = true


// File: crates/openapi/src/openapi.rs

use crate::routes;

#[derive(utoipa::OpenApi)]
#[openapi(
    info(
        title = "Hyperswitch - API Documentation",
        contact(
            name = "Hyperswitch Support",
            url = "https://hyperswitch.io",
            email = "hyperswitch@juspay.in"
        ),
        // terms_of_service = "https://www.juspay.io/terms",
        description = r#"
## Get started

Hyperswitch provides a collection of APIs that enable you to process and manage payments.
Our APIs accept and return JSON in the HTTP body, and return standard HTTP response codes.

You can consume the APIs directly using your favorite HTTP/REST library.

We have a testing environment referred to "sandbox", which you can setup to test API calls without
affecting production data.
Currently, our sandbox environment is live while our production environment is under development
and will be available soon.
You can sign up on our Dashboard to get API keys to access Hyperswitch API.

### Environment

Use the following base URLs when making requests to the APIs:

| Environment   |  Base URL                          |
|---------------|------------------------------------|
| Sandbox       | <https://sandbox.hyperswitch.io>   |
| Production    | <https://api.hyperswitch.io>       |

## Authentication

When you sign up on our [dashboard](https://app.hyperswitch.io) and create a merchant
account, you are given a secret key (also referred as api-key) and a publishable key.
You may authenticate all API requests with Hyperswitch server by providing the appropriate key in
the request Authorization header.

| Key             |  Description                                                                                |
|-----------------|-----------------------------------------------------------------------------------------------|
| api-key         | Private key. Used to authenticate all API requests from your merchant server                  |
| publishable key | Unique identifier for your account. Used to authenticate API requests from your app's client  |

Never share your secret api keys. Keep them guarded and secure.
"#,
    ),
    servers(
        (url = "https://sandbox.hyperswitch.io", description = "Sandbox Environment")
    ),
    tags(
        (name = "Merchant Account", description = "Create and manage merchant accounts"),
        (name = "Profile", description = "Create and manage profiles"),
        (name = "Merchant Connector Account", description = "Create and manage merchant connector accounts"),
        (name = "Payments", description = "Create and manage one-time payments, recurring payments and mandates"),
        (name = "Refunds", description = "Create and manage refunds for successful payments"),
        (name = "Mandates", description = "Manage mandates"),
        (name = "Customers", description = "Create and manage customers"),
        (name = "Payment Methods", description = "Create and manage payment methods of customers"),
        (name = "Disputes", description = "Manage disputes"),
        (name = "API Key", description = "Create and manage API Keys"),
        (name = "Payouts", description = "Create and manage payouts"),
        (name = "payment link", description = "Create payment link"),
        (name = "Routing", description = "Create and manage routing configurations"),
        (name = "Event", description = "Manage events"),
        (name = "Authentication", description = "Create and manage authentication"),
        (name = "Subscriptions", description = "Subscription management and billing endpoints")
    ),
    // The paths will be displayed in the same order as they are registered here
    paths(
        // Routes for payments
        routes::payments::payments_create,
        routes::payments::payments_update,
        routes::payments::payments_confirm,
        routes::payments::payments_retrieve,
        routes::payments::payments_capture,
        routes::payments::payments_connector_session,
        routes::payments::payments_cancel,
        routes::payments::payments_cancel_post_capture,
        routes::payments::payments_extend_authorization,
        routes::payments::payments_list,
        routes::payments::payments_incremental_authorization,
        routes::payment_link::payment_link_retrieve,
        routes::payments::payments_external_authentication,
        routes::payments::payments_complete_authorize,
        routes::payments::payments_post_session_tokens,
        routes::payments::payments_update_metadata,
        routes::payments::payments_submit_eligibility,

        // Routes for relay
        routes::relay::relay,
        routes::relay::relay_retrieve,

        // Routes for refunds
        routes::refunds::refunds_create,
        routes::refunds::refunds_retrieve,
        routes::refunds::refunds_update,
        routes::refunds::refunds_list,

        // Routes for Organization
        routes::organization::organization_create,
        routes::organization::organization_retrieve,
        routes::organization::organization_update,

        // Routes for merchant account
        routes::merchant_account::merchant_account_create,
        routes::merchant_account::retrieve_merchant_account,
        routes::merchant_account::update_merchant_account,
        routes::merchant_account::delete_merchant_account,
        routes::merchant_account::merchant_account_kv_status,

        // Routes for merchant connector account
        routes::merchant_connector_account::connector_create,
        routes::merchant_connector_account::connector_retrieve,
        routes::merchant_connector_account::connector_list,
        routes::merchant_connector_account::connector_update,
        routes::merchant_connector_account::connector_delete,

        //Routes for gsm
        routes::gsm::create_gsm_rule,
        routes::gsm::get_gsm_rule,
        routes::gsm::update_gsm_rule,
        routes::gsm::delete_gsm_rule,

        // Routes for mandates
        routes::mandates::get_mandate,
        routes::mandates::revoke_mandate,
        routes::mandates::customers_mandates_list,

        //Routes for customers
        routes::customers::customers_create,
        routes::customers::customers_retrieve,
        routes::customers::customers_list,
        routes::customers::customers_update,
        routes::customers::customers_delete,

        //Routes for payment methods
        routes::payment_method::create_payment_method_api,
        routes::payment_method::list_payment_method_api,
        routes::payment_method::list_customer_payment_method_api,
        routes::payment_method::list_customer_payment_method_api_client,
        routes::payment_method::default_payment_method_set_api,
        routes::payment_method::payment_method_retrieve_api,
        routes::payment_method::payment_method_update_api,
        routes::payment_method::payment_method_delete_api,

        // Routes for Profile
        routes::profile::profile_create,
        routes::profile::profile_list,
        routes::profile::profile_retrieve,
        routes::profile::profile_update,
        routes::profile::profile_delete,

        // Routes for disputes
        routes::disputes::retrieve_dispute,
        routes::disputes::retrieve_disputes_list,

        // Routes for routing
        routes::routing::routing_create_config,
        routes::routing::routing_link_config,
        routes::routing::routing_retrieve_config,
        routes::routing::list_routing_configs,
        routes::routing::routing_unlink_config,
        routes::routing::routing_update_default_config,
        routes::routing::routing_retrieve_default_config,
        routes::routing::routing_retrieve_linked_config,
        routes::routing::routing_retrieve_default_config_for_profiles,
        routes::routing::routing_update_default_config_for_profile,
        routes::routing::success_based_routing_update_configs,
        routes::routing::toggle_success_based_routing,
        routes::routing::toggle_elimination_routing,
        routes::routing::create_success_based_routing,
        routes::routing::create_elimination_routing,
        routes::routing::contract_based_routing_setup_config,
        routes::routing::contract_based_routing_update_configs,
        routes::routing::call_decide_gateway_open_router,
        routes::routing::call_update_gateway_score_open_router,
        routes::routing::evaluate_routing_rule,

        // Routes for blocklist
        routes::blocklist::remove_entry_from_blocklist,
        routes::blocklist::list_blocked_payment_methods,
        routes::blocklist::add_entry_to_blocklist,
        routes::blocklist::toggle_blocklist_guard,

        // Routes for payouts
        routes::payouts::payouts_create,
        routes::payouts::payouts_retrieve,
        routes::payouts::payouts_update,
        routes::payouts::payouts_cancel,
        routes::payouts::payouts_fulfill,
        routes::payouts::payouts_list,
        routes::payouts::payouts_confirm,
        routes::payouts::payouts_list_filters,
        routes::payouts::payouts_list_by_filter,

        // Routes for api keys
        routes::api_keys::api_key_create,
        routes::api_keys::api_key_retrieve,
        routes::api_keys::api_key_update,
        routes::api_keys::api_key_revoke,
        routes::api_keys::api_key_list,

        // Routes for events
        routes::webhook_events::list_initial_webhook_delivery_attempts,
        routes::webhook_events::list_initial_webhook_delivery_attempts_with_jwtauth,
        routes::webhook_events::list_webhook_delivery_attempts,
        routes::webhook_events::retry_webhook_delivery_attempt,

        // Routes for poll apis
        routes::poll::retrieve_poll_status,

        // Routes for profile acquirer account
        routes::profile_acquirer::profile_acquirer_create,
        routes::profile_acquirer::profile_acquirer_update,

        // Routes for 3DS Decision Rule
        routes::three_ds_decision_rule::three_ds_decision_rule_execute,

        // Routes for authentication
        routes::authentication::authentication_create,
        routes::authentication::authentication_eligibility,
        routes::authentication::authentication_authenticate,
        routes::authentication::authentication_redirect,
        routes::authentication::authentication_sync,
        routes::authentication::authentication_enabled_authn_methods_token,
        routes::authentication::authentication_eligibility_check,
        routes::authentication::authentication_retrieve_eligibility_check,

        // Routes for platform account
        routes::platform::create_platform_account,

        //Routes for subscriptions
        routes::subscriptions::create_and_confirm_subscription,
        routes::subscriptions::create_subscription,
        routes::subscriptions::confirm_subscription,
        routes::subscriptions::get_subscription,
        routes::subscriptions::update_subscription,
        routes::subscriptions::get_subscription_plans,
        routes::subscriptions::get_estimate,
        routes::subscriptions::pause_subscription,
        routes::subscriptions::resume_subscription,
        routes::subscriptions::cancel_subscription,
    ),
    components(schemas(
        common_utils::types::MinorUnit,
        common_utils::types::StringMinorUnit,
        common_utils::types::TimeRange,
        common_utils::link_utils::GenericLinkUiConfig,
        common_utils::link_utils::EnabledPaymentMethod,
        common_utils::payout_method_utils::AdditionalPayoutMethodData,
        common_utils::payout_method_utils::CardAdditionalData,
        common_utils::payout_method_utils::BankAdditionalData,
        common_utils::payout_method_utils::WalletAdditionalData,
        common_utils::payout_method_utils::BankRedirectAdditionalData,
        common_utils::payout_method_utils::AchBankTransferAdditionalData,
        common_utils::payout_method_utils::BacsBankTransferAdditionalData,
        common_utils::payout_method_utils::SepaBankTransferAdditionalData,
        common_utils::payout_method_utils::PixBankTransferAdditionalData,
        common_utils::payout_method_utils::PaypalAdditionalData,
        common_utils::payout_method_utils::InteracAdditionalData,
        common_utils::payout_method_utils::VenmoAdditionalData,
        common_utils::payout_method_utils::ApplePayDecryptAdditionalData,
        common_utils::payout_method_utils::PassthroughAddtionalData,
        common_types::payments::SplitPaymentsRequest,
        common_types::payments::GpayTokenizationData,
        common_types::payments::GPayPredecryptData,
        common_types::payments::GpayEcryptedTokenizationData,
        common_types::payments::ApplePayPaymentData,
        common_types::payments::ApplePayPredecryptData,
        common_types::payments::ApplePayCryptogramData,
        common_types::payments::StripeSplitPaymentRequest,
        common_types::domain::AdyenSplitData,
        common_types::domain::AdyenSplitItem,
        common_types::payments::AcceptanceType,
        common_types::payments::CustomerAcceptance,
        common_types::payments::OnlineMandate,
        common_types::payments::XenditSplitRequest,
        common_types::payments::XenditSplitRoute,
        common_types::payments::XenditChargeResponseData,
        common_types::payments::XenditMultipleSplitResponse,
        common_types::payments::XenditMultipleSplitRequest,
        common_types::domain::XenditSplitSubMerchantData,
        common_utils::types::ChargeRefunds,
        common_types::refunds::SplitRefund,
        common_types::refunds::StripeSplitRefundRequest,
        common_types::payments::ConnectorChargeResponseData,
        common_types::payments::StripeChargeResponseData,
        common_types::three_ds_decision_rule_engine::ThreeDSDecisionRule,
        common_types::three_ds_decision_rule_engine::ThreeDSDecision,
        common_types::payments::MerchantCountryCode,
        common_types::payments::BillingDescriptor,
        common_types::payments::PartnerMerchantIdentifierDetails,
        common_types::payments::PartnerApplicationDetails,
        common_types::payments::MerchantApplicationDetails,
        api_models::enums::PaymentChannel,
        api_models::three_ds_decision_rule::ThreeDsDecisionRuleExecuteRequest,
        api_models::three_ds_decision_rule::ThreeDsDecisionRuleExecuteResponse,
        api_models::three_ds_decision_rule::PaymentData,
        api_models::three_ds_decision_rule::PaymentMethodMetaData,
        api_models::three_ds_decision_rule::CustomerDeviceData,
        api_models::three_ds_decision_rule::IssuerData,
        api_models::three_ds_decision_rule::AcquirerData,
        api_models::payments::CartesBancairesParams,
        api_models::payments::NetworkParams,
        api_models::payments::Cryptogram,
        api_models::payments::ExternalThreeDsData,
        api_models::refunds::RefundRequest,
        api_models::refunds::RefundType,
        api_models::refunds::RefundResponse,
        api_models::refunds::RefundStatus,
        api_models::refunds::RefundUpdateRequest,
        api_models::organization::OrganizationCreateRequest,
        api_models::organization::OrganizationUpdateRequest,
        api_models::organization::OrganizationResponse,
        api_models::admin::MerchantAccountCreate,
        api_models::admin::MerchantAccountUpdate,
        api_models::admin::MerchantAccountDeleteResponse,
        api_models::admin::MerchantConnectorDeleteResponse,
        api_models::admin::MerchantConnectorResponse,
        api_models::admin::MerchantConnectorListResponse,
        api_models::admin::AuthenticationConnectorDetails,
        api_models::admin::ExtendedCardInfoConfig,
        api_models::admin::BusinessGenericLinkConfig,
        api_models::admin::BusinessCollectLinkConfig,
        api_models::admin::BusinessPayoutLinkConfig,
        api_models::admin::CardTestingGuardConfig,
        api_models::admin::CardTestingGuardStatus,
        api_models::customers::CustomerRequest,
        api_models::customers::CustomerUpdateRequest,
        api_models::customers::CustomerDeleteResponse,
        api_models::payment_methods::PaymentMethodCreate,
        api_models::payment_methods::PaymentMethodResponse,
        api_models::payment_methods::CustomerPaymentMethodUpdateResponse,
        api_models::payment_methods::CustomerPaymentMethod,
        common_types::three_ds_decision_rule_engine::ThreeDSDecisionRule,
        common_types::domain::AcquirerConfigMap,
        common_types::domain::AcquirerConfig,
        api_models::payment_methods::PaymentMethodListResponse,
        api_models::payment_methods::PaymentMethodDataWalletInfo,
        api_models::payment_methods::ResponsePaymentMethodsEnabled,
        api_models::payment_methods::ResponsePaymentMethodTypes,
        api_models::payment_methods::PaymentExperienceTypes,
        api_models::payment_methods::CardNetworkTypes,
        api_models::payment_methods::BankDebitTypes,
        api_models::payment_methods::BankTransferTypes,
        api_models::payment_methods::CustomerPaymentMethodsListResponse,
        api_models::payment_methods::PaymentMethodDeleteResponse,
        api_models::payment_methods::PaymentMethodUpdate,
        api_models::payment_methods::CustomerDefaultPaymentMethodResponse,
        api_models::payment_methods::CardDetailFromLocker,
        api_models::payment_methods::PaymentMethodCreateData,
        api_models::payment_methods::CardDetail,
        api_models::payment_methods::CardDetailUpdate,
        api_models::payment_methods::RequestPaymentMethodTypes,
        api_models::poll::PollResponse,
        api_models::poll::PollStatus,
        api_models::customers::CustomerResponse,
        api_models::admin::AcceptedCountries,
        api_models::admin::AcceptedCurrencies,
        api_models::enums::CustomTermsByPaymentMethodTypes,
        api_models::enums::AdyenSplitType,
        api_models::enums::PaymentType,
        api_models::enums::MitCategory,
        api_models::enums::ScaExemptionType,
        api_models::enums::PaymentMethod,
        api_models::enums::TriggeredBy,
        api_models::enums::TokenDataType,
        api_models::enums::PaymentMethodType,
        api_models::enums::ConnectorType,
        api_models::enums::PayoutConnectors,
        api_models::enums::AuthenticationConnectors,
        api_models::enums::Currency,
        api_models::enums::CavvAlgorithm,
        api_models::enums::ExemptionIndicator,
        api_models::enums::DocumentKind,
        api_models::enums::IntentStatus,
        api_models::enums::CaptureMethod,
        api_models::enums::FutureUsage,
        api_models::enums::AuthenticationType,
        api_models::enums::Connector,
        api_models::enums::PaymentMethod,
        api_models::enums::PaymentMethodIssuerCode,
        api_models::enums::TaxStatus,
        api_models::enums::MandateStatus,
        api_models::enums::PaymentExperience,
        api_models::enums::BankNames,
        api_models::enums::BankType,
        api_models::enums::BankHolderType,
        api_models::enums::CardNetwork,
        api_models::enums::MerchantCategoryCode,
        api_models::enums::DisputeStage,
        api_models::enums::DisputeStatus,
        api_models::enums::CountryAlpha2,
        api_models::enums::Country,
        api_models::enums::CountryAlpha3,
        api_models::enums::FieldType,
        api_models::enums::FrmAction,
        api_models::enums::FrmPreferredFlowTypes,
        api_models::enums::RetryAction,
        api_models::enums::AttemptStatus,
        api_models::enums::CaptureStatus,
        api_models::enums::ReconStatus,
        api_models::enums::ConnectorStatus,
        api_models::enums::AuthorizationStatus,
        api_models::enums::ElementPosition,
        api_models::enums::ElementSize,
        api_models::enums::SizeVariants,
        api_models::enums::MerchantProductType,
        api_models::enums::PaymentLinkDetailsLayout,
        api_models::enums::PaymentMethodStatus,
        api_models::enums::UIWidgetFormLayout,
        api_models::enums::MerchantProductType,
        api_models::enums::HyperswitchConnectorCategory,
        api_models::enums::ConnectorIntegrationStatus,
        api_models::enums::CardDiscovery,
        api_models::enums::FeatureStatus,
        api_models::enums::MerchantProductType,
        api_models::enums::CtpServiceProvider,
        api_models::enums::PaymentLinkSdkLabelType,
        api_models::enums::OrganizationType,
        api_models::enums::PaymentLinkShowSdkTerms,
        api_models::enums::ExternalVaultEnabled,
        api_models::enums::GooglePayCardFundingSource,
        api_models::enums::VaultSdk,
        api_models::enums::VaultTokenType,
        api_models::admin::ExternalVaultConnectorDetails,
        api_models::admin::VaultTokenField,
        api_models::admin::MerchantConnectorCreate,
        api_models::admin::AdditionalMerchantData,
        api_models::admin::ConnectorWalletDetails,
        api_models::admin::MerchantRecipientData,
        api_models::admin::MerchantAccountData,
        api_models::admin::MerchantConnectorUpdate,
        api_models::admin::PrimaryBusinessDetails,
        api_models::admin::FrmConfigs,
        api_models::admin::FrmPaymentMethod,
        api_models::admin::FrmPaymentMethodType,
        api_models::admin::PaymentMethodsEnabled,
        api_models::admin::MerchantConnectorDetailsWrap,
        api_models::admin::MerchantConnectorDetails,
        api_models::admin::MerchantConnectorWebhookDetails,
        api_models::admin::ProfileCreate,
        api_models::admin::ProfileResponse,
        api_models::admin::BusinessPaymentLinkConfig,
        api_models::admin::PaymentLinkBackgroundImageConfig,
        api_models::admin::PaymentLinkConfigRequest,
        api_models::admin::PaymentLinkConfig,
        api_models::admin::PaymentLinkTransactionDetails,
        api_models::admin::TransactionDetailsUiConfiguration,
        api_models::disputes::DisputeResponse,
        api_models::disputes::DisputeResponsePaymentsRetrieve,
        api_models::gsm::GsmCreateRequest,
        api_models::gsm::GsmRetrieveRequest,
        api_models::gsm::GsmUpdateRequest,
        api_models::gsm::GsmDeleteRequest,
        api_models::gsm::GsmDeleteResponse,
        api_models::gsm::GsmResponse,
        api_models::enums::GsmDecision,
        api_models::enums::GsmFeature,
        common_types::domain::GsmFeatureData,
        common_types::domain::RetryFeatureData,
        api_models::payments::AddressDetails,
        api_models::payments::BankDebitData,
        api_models::payments::AliPayQr,
        api_models::payments::AliPayRedirection,
        api_models::payments::MomoRedirection,
        api_models::payments::TouchNGoRedirection,
        api_models::payments::GcashRedirection,
        api_models::payments::KakaoPayRedirection,
        api_models::payments::AliPayHkRedirection,
        api_models::payments::GoPayRedirection,
        api_models::payments::MbWayRedirection,
        api_models::payments::MobilePayRedirection,
        api_models::payments::WeChatPayRedirection,
        api_models::payments::WeChatPayQr,
        api_models::payments::BankDebitBilling,
        api_models::payments::CryptoData,
        api_models::payments::RewardData,
        api_models::payments::UpiData,
        api_models::payments::UpiCollectData,
        api_models::payments::UpiIntentData,
        api_models::payments::UpiQrData,
        api_models::payments::VoucherData,
        api_models::payments::BoletoVoucherData,
        api_models::payments::AlfamartVoucherData,
        api_models::payments::IndomaretVoucherData,
        api_models::payments::Address,
        api_models::payments::VoucherData,
        api_models::payments::JCSVoucherData,
        api_models::payments::AlfamartVoucherData,
        api_models::payments::IndomaretVoucherData,
        api_models::payments::BankRedirectData,
        api_models::payments::RealTimePaymentData,
        api_models::payments::BankRedirectBilling,
        api_models::payments::BankRedirectBilling,
        api_models::payments::ConnectorMetadata,
        api_models::payments::FeatureMetadata,
        api_models::payments::ApplepayConnectorMetadataRequest,
        api_models::payments::SessionTokenInfo,
        api_models::payments::PaymentProcessingDetailsAt,
        api_models::payments::ApplepayInitiative,
        api_models::payments::PaymentProcessingDetails,
        api_models::payments::PaymentMethodDataResponseWithBilling,
        api_models::payments::PaymentMethodDataResponse,
        api_models::payments::CardResponse,
        api_models::payments::PaylaterResponse,
        api_models::payments::KlarnaSdkPaymentMethodResponse,
        api_models::payments::SwishQrData,
        api_models::payments::RevolutPayData,
        api_models::payments::AirwallexData,
        api_models::payments::BraintreeData,
        api_models::payments::NoonData,
        api_models::payments::OrderDetailsWithAmount,
        api_models::payments::NextActionType,
        api_models::payments::WalletData,
        api_models::payments::NextActionData,
        api_models::payments::PayLaterData,
        api_models::payments::MandateData,
        api_models::payments::PhoneDetails,
        api_models::payments::PaymentMethodData,
        api_models::payments::PaymentMethodDataRequest,
        api_models::payments::MandateType,
        api_models::payments::MandateAmountData,
        api_models::payments::Card,
        api_models::payments::CardRedirectData,
        api_models::payments::CardToken,
        api_models::payments::PaymentsRequest,
        api_models::payments::PaymentsCreateRequest,
        api_models::payments::PaymentsUpdateRequest,
        api_models::payments::PaymentsConfirmRequest,
        api_models::payments::PaymentsResponse,
        api_models::payments::PaymentsCreateResponseOpenApi,
        api_models::payments::PaymentsEligibilityRequest,
        api_models::payments::PaymentsEligibilityResponse,
        api_models::payments::PaymentsCreateResponseOpenApi,
        api_models::errors::types::GenericErrorResponseOpenApi,
        api_models::payments::PaymentRetrieveBody,
        api_models::payments::PaymentsRetrieveRequest,
        api_models::payments::PaymentsCaptureRequest,
        api_models::payments::PaymentsSessionRequest,
        api_models::payments::PaymentsSessionResponse,
        api_models::payments::PazeWalletData,
        api_models::payments::SessionToken,
        api_models::payments::ApplePaySessionResponse,
        api_models::payments::NullObject,
        api_models::payments::ThirdPartySdkSessionResponse,
        api_models::payments::NoThirdPartySdkSessionResponse,
        api_models::payments::SecretInfoToInitiateSdk,
        api_models::payments::ApplePayPaymentRequest,
        api_models::payments::ApplePayBillingContactFields,
        api_models::payments::ApplePayShippingContactFields,
        api_models::payments::ApplePayRecurringPaymentRequest,
        api_models::payments::ApplePayRegularBillingRequest,
        api_models::payments::ApplePayPaymentTiming,
        api_models::payments::RecurringPaymentIntervalUnit,
        api_models::payments::ApplePayRecurringDetails,
        api_models::payments::ApplePayRegularBillingDetails,
        api_models::payments::ApplePayAddressParameters,
        api_models::payments::AmountInfo,
        api_models::payments::ClickToPaySessionResponse,
        api_models::enums::ProductType,
        api_models::enums::MerchantAccountType,
        api_models::enums::MerchantAccountRequestType,
        api_models::payments::GooglePayWalletData,
        api_models::payments::PayPalWalletData,
        api_models::payments::PaypalRedirection,
        api_models::payments::GpayMerchantInfo,
        api_models::payments::GpayAllowedPaymentMethods,
        api_models::payments::GpayAllowedMethodsParameters,
        api_models::payments::GpayTokenizationSpecification,
        api_models::payments::GpayTokenParameters,
        api_models::payments::GpayTransactionInfo,
        api_models::payments::GpaySessionTokenResponse,
        api_models::payments::GooglePayThirdPartySdkData,
        api_models::payments::KlarnaSessionTokenResponse,
        api_models::payments::PaypalSessionTokenResponse,
        api_models::payments::PaypalFlow,
        api_models::payments::PaypalTransactionInfo,
        api_models::payments::ApplepaySessionTokenResponse,
        api_models::payments::SdkNextAction,
        api_models::payments::NextActionCall,
        api_models::payments::SdkNextActionData,
        api_models::payments::SamsungPayWalletData,
        api_models::payments::WeChatPay,
        api_models::payments::GooglePayPaymentMethodInfo,
        api_models::payments::ApplePayWalletData,
        api_models::payments::SamsungPayWalletCredentials,
        api_models::payments::SamsungPayWebWalletData,
        api_models::payments::SamsungPayAppWalletData,
        api_models::payments::SamsungPayCardBrand,
        api_models::payments::SamsungPayTokenData,
        api_models::payments::ApplepayPaymentMethod,
        api_models::payments::PaymentsCancelRequest,
        api_models::payments::PaymentsCancelPostCaptureRequest,
        api_models::payments::PaymentListConstraints,
        api_models::payments::PaymentListResponse,
        api_models::payments::CashappQr,
        api_models::payments::BankTransferData,
        api_models::payments::BankTransferNextStepsData,
        api_models::payments::SepaAndBacsBillingDetails,
        api_models::payments::AchBillingDetails,
        api_models::payments::MultibancoBillingDetails,
        api_models::payments::DokuBillingDetails,
        api_models::payments::BankTransferInstructions,
        api_models::payments::MobilePaymentNextStepData,
        api_models::payments::MobilePaymentConsent,
        api_models::payments::IframeData,
        api_models::payments::ReceiverDetails,
        api_models::payments::AchTransfer,
        api_models::payments::MultibancoTransferInstructions,
        api_models::payments::DokuBankTransferInstructions,
        api_models::payments::AmazonPayRedirectData,
        api_models::payments::SkrillData,
        api_models::payments::PayseraData,
        api_models::payments::ApplePayRedirectData,
        api_models::payments::ApplePayThirdPartySdkData,
        api_models::payments::GooglePayRedirectData,
        api_models::payments::GooglePayThirdPartySdk,
        api_models::payments::GooglePaySessionResponse,
        api_models::payments::PazeSessionTokenResponse,
        api_models::payments::SamsungPaySessionTokenResponse,
        api_models::payments::SamsungPayMerchantPaymentInformation,
        api_models::payments::SamsungPayAmountDetails,
        api_models::payments::SamsungPayAmountFormat,
        api_models::payments::SamsungPayProtocolType,
        api_models::payments::GpayShippingAddressParameters,
        api_models::payments::GpayBillingAddressParameters,
        api_models::payments::GpayBillingAddressFormat,
        api_models::payments::NetworkDetails,
        api_models::payments::SepaBankTransferInstructions,
        api_models::payments::BacsBankTransferInstructions,
        api_models::payments::RedirectResponse,
        api_models::payments::RequestSurchargeDetails,
        api_models::payments::PaymentAttemptResponse,
        api_models::payments::CaptureResponse,
        api_models::payments::PaymentsIncrementalAuthorizationRequest,
        api_models::payments::IncrementalAuthorizationResponse,
        api_models::payments::PaymentsCompleteAuthorizeRequest,
        api_models::payments::PaymentsExternalAuthenticationRequest,
        api_models::payments::PaymentsExternalAuthenticationResponse,
        api_models::payments::SdkInformation,
        api_models::payments::DeviceChannel,
        api_models::payments::ThreeDsCompletionIndicator,
        api_models::payments::MifinityData,
        api_models::enums::TransactionStatus,
        api_models::payments::BrowserInformation,
        api_models::payments::PaymentCreatePaymentLinkConfig,
        api_models::payments::ThreeDsData,
        api_models::payments::ThreeDsMethodData,
        api_models::payments::ThreeDsMethodKey,
        api_models::payments::PollConfigResponse,
        api_models::payments::PollConfig,
        api_models::payments::ExternalAuthenticationDetailsResponse,
        api_models::payments::ExtendedCardInfo,
        api_models::payments::AmazonPaySessionTokenData,
        api_models::payments::AmazonPayMerchantCredentials,
        api_models::payments::AmazonPayWalletData,
        api_models::payments::AmazonPaySessionTokenResponse,
        api_models::payments::AmazonPayPaymentIntent,
        api_models::payments::AmazonPayDeliveryOptions,
        api_models::payments::AmazonPayDeliveryPrice,
        api_models::payments::AmazonPayShippingMethod,
        api_models::payment_methods::RequiredFieldInfo,
        api_models::payment_methods::DefaultPaymentMethod,
        api_models::payment_methods::MaskedBankDetails,
        api_models::payment_methods::SurchargeDetailsResponse,
        api_models::payment_methods::SurchargeResponse,
        api_models::payment_methods::SurchargePercentage,
        api_models::payment_methods::PaymentMethodCollectLinkRequest,
        api_models::payment_methods::PaymentMethodCollectLinkResponse,
        api_models::payment_methods::CardType,
        api_models::payment_methods::CardNetworkTokenizeRequest,
        api_models::payment_methods::CardNetworkTokenizeResponse,
        api_models::payment_methods::TokenizeDataRequest,
        api_models::payment_methods::TokenizeCardRequest,
        api_models::payment_methods::TokenizePaymentMethodRequest,
        api_models::refunds::RefundListRequest,
        api_models::refunds::RefundListResponse,
        api_models::relay::RelayRequest,
        api_models::relay::RelayResponse,
        api_models::enums::RelayType,
        api_models::relay::RelayData,
        api_models::relay::RelayRefundRequestData,
        api_models::enums::RelayStatus,
        api_models::relay::RelayError,
        api_models::payments::AmountFilter,
        api_models::mandates::MandateRevokedResponse,
        api_models::mandates::MandateResponse,
        api_models::mandates::MandateCardDetails,
        api_models::mandates::RecurringDetails,
        api_models::mandates::NetworkTransactionIdAndCardDetails,
        api_models::mandates::ProcessorPaymentToken,
        api_models::ephemeral_key::EphemeralKeyCreateResponse,
        api_models::payments::CustomerDetails,
        api_models::payments::GiftCardData,
        api_models::payments::GiftCardDetails,
        api_models::payments::BHNGiftCardDetails,
        api_models::payments::MobilePaymentData,
        api_models::payments::MobilePaymentResponse,
        api_models::payments::Address,
        api_models::payments::BankCodeResponse,
        api_models::payouts::CardPayout,
        api_models::payouts::Wallet,
        api_models::payouts::Paypal,
        api_models::payouts::BankRedirect,
        api_models::payouts::Interac,
        api_models::payouts::Venmo,
        api_models::payouts::AchBankTransfer,
        api_models::payouts::BacsBankTransfer,
        api_models::payouts::SepaBankTransfer,
        api_models::payouts::PixBankTransfer,
        api_models::payouts::PayoutsCreateRequest,
        api_models::payouts::PayoutUpdateRequest,
        api_models::payouts::PayoutConfirmRequest,
        api_models::payouts::PayoutCancelRequest,
        api_models::payouts::PayoutFulfillRequest,
        api_models::payouts::PayoutRetrieveRequest,
        api_models::payouts::PayoutAttemptResponse,
        api_models::payouts::PayoutCreateResponse,
        api_models::payouts::PayoutListConstraints,
        api_models::payouts::PayoutListFilters,
        api_models::payouts::PayoutListFilterConstraints,
        api_models::payouts::PayoutListResponse,
        api_models::payouts::PayoutRetrieveBody,
        api_models::payouts::PayoutMethodData,
        api_models::payouts::Passthrough,
        api_models::payouts::PayoutMethodDataResponse,
        api_models::payouts::PayoutLinkResponse,
        api_models::payouts::Bank,
        api_models::payouts::ApplePayDecrypt,
        api_models::payouts::PayoutCreatePayoutLinkConfig,
        api_models::enums::PayoutEntityType,
        api_models::enums::PayoutSendPriority,
        api_models::enums::PayoutStatus,
        api_models::enums::PayoutType,
        api_models::enums::TransactionType,
        api_models::payments::FrmMessage,
        api_models::webhooks::OutgoingWebhook,
        api_models::webhooks::OutgoingWebhookContent,
        api_models::enums::EventClass,
        api_models::enums::EventType,
        api_models::enums::DecoupledAuthenticationType,
        api_models::enums::Tokenization,
        api_models::enums::AuthenticationStatus,
        api_models::admin::MerchantAccountResponse,
        api_models::admin::MerchantConnectorId,
        api_models::admin::MerchantDetails,
        api_models::admin::ToggleKVRequest,
        api_models::admin::ToggleKVResponse,
        api_models::admin::WebhookDetails,
        api_models::api_keys::ApiKeyExpiration,
        api_models::api_keys::CreateApiKeyRequest,
        api_models::api_keys::CreateApiKeyResponse,
        api_models::api_keys::RetrieveApiKeyResponse,
        api_models::api_keys::RevokeApiKeyResponse,
        api_models::api_keys::UpdateApiKeyRequest,
        api_models::payments::RetrievePaymentLinkRequest,
        api_models::payments::PaymentLinkResponse,
        api_models::payments::RetrievePaymentLinkResponse,
        api_models::payments::PaymentLinkInitiateRequest,
        api_models::payouts::PayoutLinkInitiateRequest,
        api_models::payments::ExtendedCardInfoResponse,
        api_models::payments::GooglePayAssuranceDetails,
        api_models::routing::RoutingConfigRequest,
        api_models::routing::RoutingDictionaryRecord,
        api_models::routing::RoutingKind,
        api_models::routing::RoutableConnectorChoice,
        api_models::routing::DynamicRoutingFeatures,
        api_models::routing::SuccessBasedRoutingConfig,
        api_models::routing::DynamicRoutingConfigParams,
        api_models::routing::CurrentBlockThreshold,
        api_models::routing::SuccessBasedRoutingConfigBody,
        api_models::routing::ContractBasedRoutingConfig,
        api_models::routing::ContractBasedRoutingConfigBody,
        api_models::routing::LabelInformation,
        api_models::routing::ContractBasedTimeScale,
        api_models::routing::LinkedRoutingConfigRetrieveResponse,
        api_models::routing::RoutingRetrieveResponse,
        api_models::routing::ProfileDefaultRoutingConfig,
        api_models::routing::MerchantRoutingAlgorithm,
        api_models::routing::RoutingAlgorithmKind,
        api_models::routing::RoutingDictionary,
        api_models::routing::RoutingAlgorithmWrapper,
        api_models::routing::EliminationRoutingConfig,
        api_models::open_router::DecisionEngineEliminationData,
        api_models::routing::EliminationAnalyserConfig,
        api_models::routing::DynamicRoutingAlgorithm,
        api_models::routing::StaticRoutingAlgorithm,
        api_models::routing::StraightThroughAlgorithm,
        api_models::routing::ConnectorVolumeSplit,
        api_models::routing::ConnectorSelection,
        api_models::routing::SuccessRateSpecificityLevel,
        api_models::routing::ToggleDynamicRoutingQuery,
        api_models::routing::ToggleDynamicRoutingPath,
        api_models::routing::ProgramThreeDsDecisionRule,
        api_models::routing::RuleThreeDsDecisionRule,
        api_models::routing::RoutingVolumeSplitResponse,
        api_models::routing::ast::RoutableChoiceKind,
        api_models::enums::RoutableConnectors,
        api_models::routing::ast::ProgramConnectorSelection,
        api_models::routing::ast::RuleConnectorSelection,
        api_models::routing::ast::IfStatement,
        api_models::routing::ast::Comparison,
        api_models::routing::ast::ComparisonType,
        api_models::routing::ast::ValueType,
        api_models::routing::ast::MetadataValue,
        api_models::routing::ast::NumberComparison,
        api_models::payment_methods::RequestPaymentMethodTypes,
        api_models::payments::PaymentLinkStatus,
        api_models::blocklist::BlocklistRequest,
        api_models::blocklist::BlocklistResponse,
        api_models::blocklist::ToggleBlocklistResponse,
        api_models::blocklist::ListBlocklistQuery,
        api_models::enums::BlocklistDataKind,
        api_models::enums::ErrorCategory,
        api_models::webhook_events::EventListConstraints,
        api_models::webhook_events::EventListItemResponse,
        api_models::webhook_events::EventRetrieveResponse,
        api_models::webhook_events::OutgoingWebhookRequestContent,
        api_models::webhook_events::OutgoingWebhookResponseContent,
        api_models::webhook_events::TotalEventsResponse,
        api_models::enums::WebhookDeliveryAttempt,
        api_models::enums::PaymentChargeType,
        api_models::enums::StripeChargeType,
        api_models::payments::CustomerDetailsResponse,
        api_models::payments::SdkType,
        api_models::payments::OpenBankingData,
        api_models::payments::OpenBankingSessionToken,
        api_models::payments::BankDebitResponse,
        api_models::payments::BankRedirectResponse,
        api_models::payments::InteracPaymentMethod,
        api_models::payments::BankTransferResponse,
        api_models::payments::CardRedirectResponse,
        api_models::payments::CardTokenResponse,
        api_models::payments::CryptoResponse,
        api_models::payments::GiftCardResponse,
        api_models::payments::OpenBankingResponse,
        api_models::payments::RealTimePaymentDataResponse,
        api_models::payments::UpiResponse,
        api_models::payments::VoucherResponse,
        api_models::payments::additional_info::CardTokenAdditionalData,
        api_models::payments::additional_info::BankDebitAdditionalData,
        api_models::payments::additional_info::AchBankDebitAdditionalData,
        api_models::payments::additional_info::BacsBankDebitAdditionalData,
        api_models::payments::additional_info::BecsBankDebitAdditionalData,
        api_models::payments::additional_info::SepaBankDebitAdditionalData,
        api_models::payments::additional_info::BankRedirectDetails,
        api_models::payments::additional_info::BancontactBankRedirectAdditionalData,
        api_models::payments::additional_info::BlikBankRedirectAdditionalData,
        api_models::payments::additional_info::GiropayBankRedirectAdditionalData,
        api_models::payments::additional_info::BankTransferAdditionalData,
        api_models::payments::additional_info::PixBankTransferAdditionalData,
        api_models::payments::additional_info::LocalBankTransferAdditionalData,
        api_models::payments::additional_info::GiftCardAdditionalData,
        api_models::payments::additional_info::GivexGiftCardAdditionalData,
        api_models::payments::additional_info::UpiAdditionalData,
        api_models::payments::additional_info::UpiCollectAdditionalData,
        api_models::payments::additional_info::WalletAdditionalDataForCard,
        api_models::payments::PaymentsDynamicTaxCalculationRequest,
        api_models::payments::WalletResponse,
        api_models::payments::WalletResponseData,
        api_models::payments::PaymentsDynamicTaxCalculationResponse,
        api_models::payments::DisplayAmountOnSdk,
        api_models::payments::PaymentsPostSessionTokensRequest,
        api_models::payments::PaymentsPostSessionTokensResponse,
        api_models::payments::PaymentsUpdateMetadataRequest,
        api_models::payments::PaymentsUpdateMetadataResponse,
        api_models::payments::CtpServiceDetails,
        api_models::payments::AdyenConnectorMetadata,
        api_models::payments::AdyenTestingData,
        api_models::feature_matrix::FeatureMatrixListResponse,
        api_models::feature_matrix::FeatureMatrixRequest,
        api_models::feature_matrix::ConnectorFeatureMatrixResponse,
        api_models::feature_matrix::PaymentMethodSpecificFeatures,
        api_models::feature_matrix::CardSpecificFeatures,
        api_models::feature_matrix::SupportedPaymentMethod,
        api_models::open_router::DecisionEngineSuccessRateData,
        api_models::open_router::DecisionEngineGatewayWiseExtraScore,
        api_models::open_router::DecisionEngineSRSubLevelInputConfig,
        api_models::open_router::DecisionEngineEliminationData,
        api_models::profile_acquirer::ProfileAcquirerCreate,
        api_models::profile_acquirer::ProfileAcquirerUpdate,
        api_models::profile_acquirer::ProfileAcquirerResponse,
        euclid::frontend::dir::enums::CustomerDevicePlatform,
        euclid::frontend::dir::enums::CustomerDeviceType,
        euclid::frontend::dir::enums::CustomerDeviceDisplaySize,
        api_models::authentication::AuthenticationCreateRequest,
        api_models::authentication::AuthenticationResponse,
        api_models::authentication::AuthenticationEligibilityCheckRequest,
        api_models::authentication::AuthenticationEligibilityCheckResponse,
        api_models::authentication::AuthenticationRetrieveEligibilityCheckRequest,
        api_models::authentication::AuthenticationRetrieveEligibilityCheckResponse,
        api_models::authentication::AuthenticationEligibilityCheckData,
        api_models::authentication::AuthenticationEligibilityCheckResponseData,
        api_models::authentication::ClickToPayEligibilityCheckResponseData,
        api_models::authentication::VisaEligibilityCheckData,
        api_models::authentication::MasterCardEligibilityCheckData,
        api_models::authentication::AuthenticationSdkNextAction,
        api_models::authentication::ClickToPayEligibilityCheckData,
        api_models::authentication::AcquirerDetails,
        api_models::authentication::NextAction,
        common_utils::request::Method,
        api_models::authentication::EligibilityResponseParams,
        api_models::authentication::ThreeDsData,
        api_models::authentication::AuthenticationEligibilityRequest,
        api_models::authentication::AuthenticationEligibilityResponse,
        api_models::authentication::AuthenticationSyncRequest,
        api_models::authentication::AuthenticationSyncResponse,
        api_models::authentication::AuthenticationSessionTokenRequest,
        api_models::authentication::AuthenticationSessionResponse,
        api_models::authentication::PostAuthenticationRequestPaymentMethodData,
        api_models::authentication::AuthenticationAuthenticateRequest,
        api_models::authentication::AuthenticationAuthenticateResponse,
        api_models::authentication::ClickToPayDetails,
        api_models::authentication::AuthenticationSyncPostUpdateRequest,
        api_models::authentication::AuthenticationSessionToken,
        api_models::authentication::AuthenticationPaymentMethodType,
        api_models::authentication::AuthenticationPaymentMethodData,
        api_models::authentication::AuthenticationVaultTokenData,
        api_models::authentication::AuthenticationPaymentMethodDataResponse,
        api_models::open_router::OpenRouterDecideGatewayRequest,
        api_models::open_router::DecideGatewayResponse,
        api_models::open_router::UpdateScorePayload,
        api_models::open_router::UpdateScoreResponse,
        api_models::routing::RoutingEvaluateRequest,
        api_models::routing::RoutingEvaluateResponse,
        api_models::routing::ValueType,
        api_models::routing::DeRoutableConnectorChoice,
        api_models::routing::RoutableConnectorChoice,
        api_models::open_router::PaymentInfo,
        common_utils::id_type::PaymentId,
        common_utils::id_type::ProfileId,
        common_utils::id_type::AuthenticationId,
        api_models::open_router::RankingAlgorithm,
        api_models::open_router::TxnStatus,
        api_models::open_router::PriorityLogicOutput,
        api_models::open_router::PriorityLogicData,
        api_models::user::PlatformAccountCreateRequest,
        api_models::user::PlatformAccountCreateResponse,
        common_utils::id_type::CustomerId,
        common_utils::id_type::SubscriptionId,
        common_utils::id_type::MerchantId,
        common_utils::id_type::InvoiceId,
        common_utils::id_type::MerchantConnectorAccountId,
        api_models::enums::connector_enums::InvoiceStatus,
        api_models::subscription::ClientSecret,
        api_models::subscription::CreateAndConfirmSubscriptionRequest,
        api_models::subscription::CreateSubscriptionRequest,
        api_models::subscription::ConfirmSubscriptionRequest,
        api_models::subscription::UpdateSubscriptionRequest,
        api_models::subscription::SubscriptionResponse,
        api_models::subscription::GetPlansResponse,
        api_models::subscription::EstimateSubscriptionResponse,
        api_models::subscription::GetPlansQuery,
        api_models::subscription::EstimateSubscriptionQuery,
        api_models::subscription::ConfirmSubscriptionResponse,
        api_models::subscription::ConfirmSubscriptionPaymentDetails,
        api_models::subscription::PaymentDetails,
        api_models::subscription::CreateSubscriptionPaymentDetails,
        api_models::subscription::SubscriptionLineItem,
        api_models::subscription::SubscriptionPlanPrices,
        api_models::subscription::PaymentResponseData,
        api_models::subscription::Invoice,
        api_models::enums::SubscriptionStatus,
        api_models::subscription::PeriodUnit,
        api_models::subscription::PauseSubscriptionRequest,
        api_models::subscription::PauseSubscriptionResponse,
        api_models::subscription::ResumeSubscriptionRequest,
        api_models::subscription::ResumeSubscriptionResponse,
        api_models::subscription::CancelOption,
        api_models::subscription::UnbilledChargesOption,
        api_models::subscription::CreditOption,
        api_models::subscription::AccountReceivablesHandling,
        api_models::subscription::RefundableCreditsHandling,
        api_models::subscription::PauseOption,
        api_models::subscription::ResumeOption,
        api_models::subscription::ChargesHandling,
        api_models::subscription::UnpaidInvoicesHandling,
        api_models::subscription::CancelSubscriptionRequest,
        api_models::subscription::CancelSubscriptionResponse,
    )),
    modifiers(&SecurityAddon)
)]
// Bypass clippy lint for not being constructed
#[allow(dead_code)]
pub(crate) struct ApiDoc;

struct SecurityAddon;

impl utoipa::Modify for SecurityAddon {
    fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
        use utoipa::openapi::security::{
            ApiKey, ApiKeyValue, HttpAuthScheme, HttpBuilder, SecurityScheme,
        };

        if let Some(components) = openapi.components.as_mut() {
            components.add_security_schemes_from_iter([
                (
                    "api_key",
                    SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::with_description(
                        "api-key",
                        "Use the API key created under your merchant account from the HyperSwitch dashboard. API key is used to authenticate API requests from your merchant server only. Don't expose this key on a website or embed it in a mobile application."
                    ))),
                ),
                (
                    "admin_api_key",
                    SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::with_description(
                        "api-key",
                        "Admin API keys allow you to perform some privileged actions such as \
                        creating a merchant account and Merchant Connector account."
                    ))),
                ),
                (
                    "publishable_key",
                    SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::with_description(
                        "api-key",
                        "Publishable keys are a type of keys that can be public and have limited \
                        scope of usage."
                    ))),
                ),
                (
                    "ephemeral_key",
                    SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::with_description(
                        "api-key",
                        "Ephemeral keys provide temporary access to singular data, such as access \
                        to a single customer object for a short period of time."
                    ))),
                ),
                (
                    "jwt_key",
                    SecurityScheme::Http(HttpBuilder::new().scheme(HttpAuthScheme::Bearer).bearer_format("JWT").build())
                )
            ]);
        }
    }
}


// File: crates/openapi/src/lib.rs

pub mod routes;


// File: crates/openapi/src/routes.rs

#![allow(unused)]

pub mod api_keys;
pub mod authentication;
pub mod blocklist;
pub mod customers;
pub mod disputes;
pub mod gsm;
pub mod mandates;
pub mod merchant_account;
pub mod merchant_connector_account;
pub mod organization;
pub mod payment_link;
pub mod payment_method;
pub mod payments;
pub mod payouts;
pub mod platform;
pub mod poll;
pub mod profile;
pub mod profile_acquirer;
pub mod proxy;
pub mod refunds;
pub mod relay;
pub mod revenue_recovery;
pub mod routing;
pub mod subscriptions;
pub mod three_ds_decision_rule;
pub mod tokenization;
pub mod webhook_events;


// File: crates/openapi/src/main.rs

#[cfg(feature = "v1")]
mod openapi;
#[cfg(feature = "v2")]
mod openapi_v2;
mod routes;

#[allow(clippy::print_stdout)] // Using a logger is not necessary here
fn main() {
    #[cfg(all(feature = "v1", feature = "v2"))]
    compile_error!("features v1 and v2 are mutually exclusive, please enable only one of them");

    #[cfg(feature = "v1")]
    let relative_file_path = "api-reference/v1/openapi_spec_v1.json";

    #[cfg(feature = "v2")]
    let relative_file_path = "api-reference/v2/openapi_spec_v2.json";

    #[cfg(any(feature = "v1", feature = "v2"))]
    let mut file_path = router_env::workspace_path();

    #[cfg(any(feature = "v1", feature = "v2"))]
    file_path.push(relative_file_path);

    #[cfg(feature = "v1")]
    let openapi = <openapi::ApiDoc as utoipa::OpenApi>::openapi();
    #[cfg(feature = "v2")]
    let openapi = <openapi_v2::ApiDoc as utoipa::OpenApi>::openapi();

    #[allow(clippy::expect_used)]
    #[cfg(any(feature = "v1", feature = "v2"))]
    std::fs::write(
        &file_path,
        openapi
            .to_pretty_json()
            .expect("Failed to serialize OpenAPI specification as JSON"),
    )
    .expect("Failed to write OpenAPI specification to file");

    #[allow(clippy::expect_used)]
    #[cfg(feature = "v1")]
    {
        // TODO: Do this using utoipa::extensions after we have upgraded to 5.x
        let file_content =
            std::fs::read_to_string(&file_path).expect("Failed to read OpenAPI specification file");

        let mut lines: Vec<&str> = file_content.lines().collect();

        // Insert the new text at line 3 (index 2)
        if lines.len() > 2 {
            let new_line = "  \"x-mcp\": {\n    \"enabled\": true\n  },";
            lines.insert(2, new_line);
        }

        let modified_content = lines.join("\n");
        std::fs::write(&file_path, modified_content)
            .expect("Failed to write modified OpenAPI specification to file");
    }

    #[cfg(any(feature = "v1", feature = "v2"))]
    println!("Successfully saved OpenAPI specification file at '{relative_file_path}'");

    #[cfg(not(any(feature = "v1", feature = "v2")))]
    println!("No feature enabled to generate OpenAPI specification, please enable either 'v1' or 'v2' feature");
}