// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

//! Build script to generate Rust types from JSON schemas

use std::{env, fs, path::Path};

use serde_json::Value;

fn main() {
    // Tell cargo to rerun if schema or defaults files change
    println!("cargo:rerun-if-changed=schemas/cdk-config.json");
    println!("cargo:rerun-if-changed=config/defaults.toml");

    // Generate URL constants from schema
    if let Err(e) = generate_url_constants() {
        panic!("Failed to generate URL constants: {}", e);
    }
}

fn generate_url_constants() -> Result<(), Box<dyn std::error::Error>> {
    let schema_path = "schemas/cdk-config.json";
    let schema_str = fs::read_to_string(schema_path)?;
    let schema: Value = serde_json::from_str(&schema_str)?;

    // Navigate to the rpc_urls default values in the schema
    let rpc_urls = schema
        .get("properties")
        .and_then(|p| p.get("cdk"))
        .and_then(|cdk| cdk.get("properties"))
        .and_then(|props| props.get("rpc_urls"))
        .and_then(|rpc_urls| rpc_urls.get("default"))
        .ok_or("Could not find rpc_urls.default in schema")?;

    let mut constants = String::new();
    constants.push_str("// Auto-generated URL constants from cdk-config.json schema\n");
    constants.push_str("// DO NOT EDIT MANUALLY - Edit schemas/cdk-config.json instead\n\n");

    if let Some(urls) = rpc_urls.as_object() {
        for (network, url) in urls {
            let const_name = format!("URL_{}", network.to_uppercase());
            let url_str = url.as_str().ok_or("URL must be string")?;

            constants.push_str(&format!(
                "/// RPC endpoint URL for {} environment (auto-generated from schema).\n",
                network
            ));
            constants.push_str(&format!(
                "pub const {}: &str = \"{}\";\n\n",
                const_name, url_str
            ));
        }
    } else {
        return Err("rpc_urls.default is not an object".into());
    }

    let out_dir = env::var("OUT_DIR")?;
    let dest_path = Path::new(&out_dir).join("url_constants.rs");
    fs::write(dest_path, constants)?;

    println!("cargo:info=Generated URL constants from schema");

    Ok(())
}
