#!/usr/bin/env nu

# Build Validation Script for Rustelo Project
# Validates both SSR and WASM builds succeed without silent failures

def main [
    --strict                     # Treat warnings as errors
    --quick                      # Quick validation (check existing builds)
    --path: string = "."        # Path to project root
] {
    print "🔍 Validating Rust builds (SSR + WASM)..."

    mut issues = []

    if $quick {
        # Quick mode: check existing build artifacts
        let issues = ($issues | append (check_existing_builds $path))
    } else {
        # Full mode: perform actual builds
        let issues = ($issues | append (perform_build_validation $path $strict))
    }

    # Display results
    if ($issues | is-empty) {
        print "✅ Build validation passed!"
        return 0
    } else {
        print "❌ Build validation issues found:"
        for $issue in $issues {
            print $"  ($issue.severity): ($issue.message)"
            if ($issue.fix?) {
                print $"     Fix: ($issue.fix)"
            }
        }

        let errors = ($issues | where severity == "ERROR")
        if not ($errors | is-empty) {
            return 1
        } else if $strict {
            return 1
        } else {
            return 0
        }
    }
}

# Check existing build artifacts
def check_existing_builds [path: string] {
    mut issues = []

    print "🔍 Checking existing build artifacts..."

    # Check SSR build (server binary)
    let server_binary = $"($path)/target/debug/server"
    if not ($server_binary | path exists) {
        $issues = ($issues | append {
            severity: "WARNING"
            message: "Server binary not found"
            fix: "Run 'cargo build --bin server'"
        })
    } else {
        let server_size = ($server_binary | path stat | get size)
        print $"(ansi green)✅ Server binary exists (($server_size) bytes)(ansi reset)"
    }

    # Check WASM build artifacts
    let wasm_dir = $"($path)/target/front/wasm32-unknown-unknown/debug"
    if not ($wasm_dir | path exists) {
        $issues = ($issues | append {
            severity: "WARNING"
            message: "WASM build directory not found"
            fix: "Run 'cargo build --target wasm32-unknown-unknown'"
        })
    } else {
        print $"(ansi green)✅ WASM build directory exists(ansi reset)"

        # Check for client.wasm
        let wasm_files = (ls $"($wasm_dir)/*.wasm" | get name)
        if ($wasm_files | is-empty) {
            $issues = ($issues | append {
                severity: "ERROR"
                message: "No WASM files found in build directory"
                fix: "Rebuild with 'cargo leptos build'"
            })
        } else {
            for $wasm_file in $wasm_files {
                let wasm_size = ($wasm_file | path stat | get size)
                print $"(ansi green)✅ WASM file: ($wasm_file | path basename) (($wasm_size) bytes)(ansi reset)"
            }
        }
    }

    # Check site directory (leptos output)
    let site_dir = $"($path)/target/site"
    if not ($site_dir | path exists) {
        $issues = ($issues | append {
            severity: "WARNING"
            message: "Leptos site directory not found"
            fix: "Run 'cargo leptos build'"
        })
    } else {
        let pkg_dir = $"($site_dir)/pkg"
        if ($pkg_dir | path exists) {
            let js_files = (ls $"($pkg_dir)/*.js" 2>/dev/null | default [] | get name)
            let wasm_files = (ls $"($pkg_dir)/*.wasm" 2>/dev/null | default [] | get name)
            print $"(ansi green)✅ Leptos site artifacts: ($js_files | length) JS, ($wasm_files | length) WASM files(ansi reset)"
        }
    }

    $issues
}

# Perform actual build validation
def perform_build_validation [path: string, strict: bool] {
    mut issues = []

    print "🔨 Performing build validation..."

    # Set RUSTFLAGS for strict mode
    let rustflags = if $strict { "-D warnings" } else { "" }

    # Test SSR build
    print "📦 Testing SSR build..."
    let ssr_result = try {
        with-env { RUSTFLAGS: $rustflags } {
            ^cargo build --bin server --features ssr
        }
        "success"
    } catch { |e|
        $e.msg
    }

    if $ssr_result != "success" {
        $issues = ($issues | append {
            severity: "ERROR"
            message: $"SSR build failed: ($ssr_result)"
            fix: "Check Rust compilation errors in server crate"
        })
    } else {
        print $"(ansi green)✅ SSR build successful(ansi reset)"
    }

    # Test WASM build
    print "📦 Testing WASM build..."
    let wasm_result = try {
        with-env { RUSTFLAGS: $rustflags } {
            ^cargo build --package client --lib --target wasm32-unknown-unknown --no-default-features --features hydrate
        }
        "success"
    } catch { |e|
        $e.msg
    }

    if $wasm_result != "success" {
        $issues = ($issues | append {
            severity: "ERROR"
            message: $"WASM build failed: ($wasm_result)"
            fix: "Check Rust compilation errors in client crate"
        })
    } else {
        print $"(ansi green)✅ WASM build successful(ansi reset)"
    }

    # Test workspace build
    if $ssr_result == "success" and $wasm_result == "success" {
        print "📦 Testing workspace build..."
        let workspace_result = try {
            with-env { RUSTFLAGS: $rustflags } {
                ^cargo build --workspace
            }
            "success"
        } catch { |e|
            $e.msg
        }

        if $workspace_result != "success" {
            $issues = ($issues | append {
                severity: "ERROR"
                message: $"Workspace build failed: ($workspace_result)"
                fix: "Check for workspace-level compilation issues"
            })
        } else {
            print $"(ansi green)✅ Workspace build successful(ansi reset)"
        }
    }

    $issues
}

# Check build warnings and errors
def check_build_output [output: string, strict: bool] {
    mut issues = []

    # Check for common warning patterns
    let warning_patterns = [
        "warning: unused"
        "warning: dead_code"
        "warning: unreachable_code"
        "warning: unused_imports"
    ]

    for $pattern in $warning_patterns {
        if ($output | str contains $pattern) {
            let severity = if $strict { "ERROR" } else { "WARNING" }
            $issues = ($issues | append {
                severity: $severity
                message: $"Build contains warnings: ($pattern)"
                fix: "Review and fix compilation warnings"
            })
        }
    }

    $issues
}
