//! Configuration Constants Generation
//!
//! Generates compile-time configuration constants from environment variables
//! for use in both SSR and WASM contexts.

use std::env;
use std::fs;
use std::path::Path;

/// Generate configuration constants file from environment variables
/// This allows WASM to access configuration values at compile time
pub fn generate_config_constants(out_dir: &str) -> Result<(), Box<dyn std::error::Error>> {
    let out_path = Path::new(out_dir).join("config_constants.rs");

    let mut content = String::new();
    content.push_str("// Generated configuration constants from environment variables\n");
    content.push_str("// This file is auto-generated - do not edit manually!\n\n");

    // Add necessary configuration constants for URL handling
    let config_vars = [
        ("SITE_SERVER_CONTENT_URL", "/r", "URL path for serving processed content"),
        ("SITE_SERVER_ROOT_CONTENT", "r", "Server-side content loading root directory"),
        ("SERVER_HOST", "127.0.0.1", "Server host address"),
        ("SERVER_PORT", "3030", "Server port number"),
    ];

    for (var_name, default_value, description) in config_vars {
        let value = env::var(var_name).unwrap_or_else(|_| {
            eprintln!("Warning: Environment variable {} not found, using default: {}", var_name, default_value);
            default_value.to_string()
        });

        content.push_str(&format!(
            "/// {}\n/// Generated from environment variable {}\npub const {}: &str = \"{}\";\n\n",
            description,
            var_name,
            var_name,
            value.replace('"', "\\\"")
        ));
    }

    // Add getter functions for backward compatibility
    content.push_str("/// Get server content URL for client-side fetching\n");
    content.push_str("pub fn get_server_content_url() -> &'static str {\n");
    content.push_str("    SITE_SERVER_CONTENT_URL\n");
    content.push_str("}\n\n");

    content.push_str("/// Get server content root for server-side access\n");
    content.push_str("pub fn get_server_root_content() -> &'static str {\n");
    content.push_str("    SITE_SERVER_ROOT_CONTENT\n");
    content.push_str("}\n\n");

    content.push_str("/// Get full server URL for absolute client-side fetching\n");
    content.push_str("pub fn get_server_base_url() -> String {\n");
    content.push_str("    format!(\"http://{}:{}\", SERVER_HOST, SERVER_PORT)\n");
    content.push_str("}\n\n");

    content.push_str("/// Get full server content URL for absolute client-side fetching\n");
    content.push_str("pub fn get_full_server_content_url() -> String {\n");
    content.push_str("    format!(\"{}{}\", get_server_base_url(), SITE_SERVER_CONTENT_URL)\n");
    content.push_str("}\n");

    fs::write(&out_path, &content)?;

    println!("cargo:warning=Generated configuration constants at: {}", out_path.display());

    // Copy to devtools build-cache directory if SITE_DEVTOOLS_PATH is set
    if let Ok(devtools_path) = env::var("SITE_DEVTOOLS_PATH") {
        // Use the same path pattern as SmartCache system
        let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string());
        let manifest_path = Path::new(&manifest_dir);

        // Find project root by looking for workspace Cargo.toml (same logic as smart_cache)
        let mut current = manifest_path;
        let mut project_root = None;

        loop {
            let cargo_toml = current.join("Cargo.toml");
            if cargo_toml.exists() {
                if let Ok(content_str) = fs::read_to_string(&cargo_toml) {
                    if content_str.contains("[workspace]") {
                        project_root = Some(current.to_path_buf());
                        break;
                    }
                }
            }

            if let Some(parent) = current.parent() {
                current = parent;
            } else {
                break;
            }
        }

        if let Some(project_root) = project_root {
            let cache_base = if Path::new(&devtools_path).is_absolute() {
                Path::new(&devtools_path).to_path_buf()
            } else {
                project_root.join(&devtools_path)
            };

            // Get target for this build
            let target = env::var("TARGET").unwrap_or_else(|_| "unknown".to_string());
            let devtools_dir = cache_base.join("build-cache").join("core-lib").join(&target);

            if let Err(e) = fs::create_dir_all(&devtools_dir) {
                eprintln!("Warning: Failed to create devtools cache directory {}: {}", devtools_dir.display(), e);
            } else {
                let devtools_file = devtools_dir.join("config_constants.rs");
                if let Err(e) = fs::write(&devtools_file, &content) {
                    eprintln!("Warning: Failed to copy config_constants.rs to devtools: {}", e);
                } else {
                    println!("cargo:warning=Copied configuration constants to devtools: {}", devtools_file.display());
                }
            }
        }
    }

    println!("cargo:rerun-if-env-changed=SITE_SERVER_CONTENT_URL");
    println!("cargo:rerun-if-env-changed=SITE_SERVER_ROOT_CONTENT");
    println!("cargo:rerun-if-env-changed=SERVER_HOST");
    println!("cargo:rerun-if-env-changed=SERVER_PORT");
    println!("cargo:rerun-if-env-changed=SITE_DEVTOOLS_PATH");

    Ok(())
}
