//! Build utilities and helper functions

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

/// DEPRECATED: Fallback registry system removed in favor of reliable generated resources
/// This function is kept as a no-op to avoid breaking builds that might reference it
pub fn generate_fallback_registry() {
    // No-op: Fallback system removed, generated resources are now reliable
}

/// Get root path from environment variable or detect project root
pub fn get_root_path(manifest_dir: &str) -> Result<String, String> {
    // Check for explicit ROOT_PATH environment variable first
    if let Ok(root_path) = env::var("ROOT_PATH") {
        let path = Path::new(&root_path);
        if path.exists() {
            return Ok(root_path);
        } else {
            return Err(format!("ROOT_PATH {root_path} does not exist"));
        }
    }

    // Detect project root by looking for workspace Cargo.toml
    let manifest_path = Path::new(manifest_dir);
    let mut current = manifest_path;

    while let Some(parent) = current.parent() {
        let workspace_toml = parent.join("Cargo.toml");
        if workspace_toml.exists() {
            // Check if it's a workspace by reading the file
            match std::fs::read_to_string(&workspace_toml) {
                Ok(content) => {
                    if content.contains("[workspace]") {
                        return Ok(parent.to_string_lossy().to_string());
                    }
                }
                Err(e) => {
                    eprintln!("Warning: Could not read workspace Cargo.toml: {e}");
                }
            }
        }

        current = parent;
    }

    // Fallback to detected project root (go up 2 levels from shared crate)
    let fallback_path = manifest_path
        .parent()
        .and_then(|p| p.parent())
        .ok_or_else(|| "Could not determine project root path".to_string())?;

    Ok(fallback_path.to_string_lossy().to_string())
}

/// Get content root path from environment variable or default
pub fn get_content_root_path(project_root: &str) -> String {
    // Check for SITE_CONTENT_PATH environment variable first
    if let Ok(content_path) = env::var("SITE_CONTENT_PATH") {
        // If it's an absolute path, use it as-is
        if Path::new(&content_path).is_absolute() {
            return content_path;
        }

        // If it's a relative path, combine with project root
        let combined_path = Path::new(project_root).join(&content_path);
        return combined_path.to_string_lossy().to_string();
    }

    // Default to "site/content" directory in project root (new site structure)
    Path::new(project_root)
        .join("site/content")
        .to_string_lossy()
        .to_string()
}

/// Setup cargo rerun triggers for build dependencies
pub fn setup_cargo_rerun_triggers(_root_path: &str, content_root: &str) {
    // Tell cargo to rerun if content directory changes
    println!("cargo:rerun-if-changed={content_root}/");
    println!("cargo:rerun-if-changed=build.rs");

    // Also watch for SITE_CONTENT_PATH environment variable changes
    println!("cargo:rerun-if-env-changed=SITE_CONTENT_PATH");
}

/// Setup cargo config flags
pub fn setup_cargo_config() {
    // Tell cargo about our custom cfg attributes
    println!("cargo::rustc-check-cfg=cfg(has_generated_resources)");
    println!("cargo::rustc-check-cfg=cfg(use_fallback_resources)");
}

/// Convert snake_case to PascalCase
#[allow(dead_code)]
pub fn to_pascal_case(s: &str) -> String {
    s.split('_')
        .map(|word| {
            let mut chars = word.chars();
            match chars.next() {
                None => String::new(),
                Some(first) => {
                    first.to_uppercase().collect::<String>() + &chars.as_str().to_lowercase()
                }
            }
        })
        .collect()
}

/// Default enabled value for route parsing
pub fn default_enabled() -> bool {
    true
}
