#!/bin/bash

# Rustelo Setup Verification Script
# This script verifies that all required tools and dependencies are properly installed

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname $(dirname "$SCRIPT_DIR"))"

echo -e "${BLUE}🔍 Rustelo Setup Verification${NC}"
echo "============================"
echo ""

# Verification results
TOTAL_CHECKS=0
PASSED_CHECKS=0
FAILED_CHECKS=0
WARNINGS=0

# Function to check if command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to check version
check_version() {
    local tool="$1"
    local current="$2"
    local required="$3"

    if [ -z "$current" ]; then
        return 1
    fi

    # Simple version comparison (works for most cases)
    local current_major=$(echo "$current" | cut -d. -f1)
    local current_minor=$(echo "$current" | cut -d. -f2)
    local required_major=$(echo "$required" | cut -d. -f1)
    local required_minor=$(echo "$required" | cut -d. -f2)

    if [ "$current_major" -gt "$required_major" ] || \
       ([ "$current_major" -eq "$required_major" ] && [ "$current_minor" -ge "$required_minor" ]); then
        return 0
    else
        return 1
    fi
}

# Function to perform a check
check_tool() {
    local tool="$1"
    local description="$2"
    local required="$3"
    local install_cmd="$4"
    local optional="${5:-false}"

    TOTAL_CHECKS=$((TOTAL_CHECKS + 1))

    echo -n "Checking $description... "

    if command_exists "$tool"; then
        # Get version if possible
        local version=""
        case "$tool" in
            "rustc")
                version=$(rustc --version 2>/dev/null | cut -d' ' -f2)
                ;;
            "cargo")
                version=$(cargo --version 2>/dev/null | cut -d' ' -f2)
                ;;
            "node")
                version=$(node --version 2>/dev/null | sed 's/v//')
                ;;
            "npm")
                version=$(npm --version 2>/dev/null)
                ;;
            "pnpm")
                version=$(pnpm --version 2>/dev/null)
                ;;
            "git")
                version=$(git --version 2>/dev/null | cut -d' ' -f3)
                ;;
            "mdbook")
                version=$(mdbook --version 2>/dev/null | cut -d' ' -f2)
                ;;
            "just")
                version=$(just --version 2>/dev/null | cut -d' ' -f2)
                ;;
            *)
                version="unknown"
                ;;
        esac

        if [ -n "$required" ] && [ "$version" != "unknown" ]; then
            if check_version "$tool" "$version" "$required"; then
                echo -e "${GREEN}✅ $version${NC}"
                PASSED_CHECKS=$((PASSED_CHECKS + 1))
            else
                echo -e "${RED}❌ $version (required: $required+)${NC}"
                if [ "$optional" = "false" ]; then
                    FAILED_CHECKS=$((FAILED_CHECKS + 1))
                    echo "  💡 Install/update: $install_cmd"
                else
                    WARNINGS=$((WARNINGS + 1))
                    echo "  ⚠️  Optional: $install_cmd"
                fi
            fi
        else
            echo -e "${GREEN}✅ $version${NC}"
            PASSED_CHECKS=$((PASSED_CHECKS + 1))
        fi
    else
        if [ "$optional" = "false" ]; then
            echo -e "${RED}❌ Not found${NC}"
            FAILED_CHECKS=$((FAILED_CHECKS + 1))
            echo "  💡 Install: $install_cmd"
        else
            echo -e "${YELLOW}⚠️  Not found (optional)${NC}"
            WARNINGS=$((WARNINGS + 1))
            echo "  💡 Install: $install_cmd"
        fi
    fi
}

# Function to check file existence
check_file() {
    local file="$1"
    local description="$2"
    local optional="${3:-false}"

    TOTAL_CHECKS=$((TOTAL_CHECKS + 1))

    echo -n "Checking $description... "

    if [ -f "$file" ]; then
        echo -e "${GREEN}✅ Found${NC}"
        PASSED_CHECKS=$((PASSED_CHECKS + 1))
    else
        if [ "$optional" = "false" ]; then
            echo -e "${RED}❌ Not found${NC}"
            FAILED_CHECKS=$((FAILED_CHECKS + 1))
        else
            echo -e "${YELLOW}⚠️  Not found (optional)${NC}"
            WARNINGS=$((WARNINGS + 1))
        fi
    fi
}

# Function to check directory existence
check_directory() {
    local dir="$1"
    local description="$2"
    local optional="${3:-false}"

    TOTAL_CHECKS=$((TOTAL_CHECKS + 1))

    echo -n "Checking $description... "

    if [ -d "$dir" ]; then
        echo -e "${GREEN}✅ Found${NC}"
        PASSED_CHECKS=$((PASSED_CHECKS + 1))
    else
        if [ "$optional" = "false" ]; then
            echo -e "${RED}❌ Not found${NC}"
            FAILED_CHECKS=$((FAILED_CHECKS + 1))
        else
            echo -e "${YELLOW}⚠️  Not found (optional)${NC}"
            WARNINGS=$((WARNINGS + 1))
        fi
    fi
}

# Function to check environment variables
check_env_var() {
    local var="$1"
    local description="$2"
    local optional="${3:-false}"

    TOTAL_CHECKS=$((TOTAL_CHECKS + 1))

    echo -n "Checking $description... "

    if [ -n "${!var}" ]; then
        echo -e "${GREEN}✅ Set${NC}"
        PASSED_CHECKS=$((PASSED_CHECKS + 1))
    else
        if [ "$optional" = "false" ]; then
            echo -e "${RED}❌ Not set${NC}"
            FAILED_CHECKS=$((FAILED_CHECKS + 1))
        else
            echo -e "${YELLOW}⚠️  Not set (optional)${NC}"
            WARNINGS=$((WARNINGS + 1))
        fi
    fi
}

# Change to project root
cd "$PROJECT_ROOT"

echo -e "${PURPLE}🔧 Core Dependencies${NC}"
echo "-------------------"

# Check core tools
check_tool "rustc" "Rust compiler" "1.75" "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
check_tool "cargo" "Cargo package manager" "1.75" "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
check_tool "node" "Node.js" "18.0" "https://nodejs.org/ or brew install node"
check_tool "npm" "npm package manager" "8.0" "comes with Node.js"
check_tool "git" "Git version control" "" "https://git-scm.com/ or brew install git"

echo ""
echo -e "${PURPLE}📚 Documentation Tools${NC}"
echo "---------------------"

# Check documentation tools
check_tool "mdbook" "mdBook documentation" "" "cargo install mdbook"
check_tool "just" "Just task runner" "" "cargo install just"

echo ""
echo -e "${PURPLE}🔧 Development Tools${NC}"
echo "-------------------"

# Check development tools
check_tool "cargo-leptos" "Cargo Leptos" "" "cargo install cargo-leptos"
check_tool "pnpm" "pnpm package manager" "" "npm install -g pnpm" true
check_tool "cargo-watch" "Cargo Watch" "" "cargo install cargo-watch" true

echo ""
echo -e "${PURPLE}📖 Documentation Plugins${NC}"
echo "-------------------------"

# Check mdBook plugins
check_tool "mdbook-linkcheck" "mdBook link checker" "" "cargo install mdbook-linkcheck" true
check_tool "mdbook-toc" "mdBook table of contents" "" "cargo install mdbook-toc" true
check_tool "mdbook-mermaid" "mdBook mermaid diagrams" "" "cargo install mdbook-mermaid" true

echo ""
echo -e "${PURPLE}📁 Project Structure${NC}"
echo "--------------------"

# Check project structure
check_file "Cargo.toml" "Cargo manifest"
check_file "package.json" "Node.js manifest"
check_file "justfile" "Just task definitions"
check_file "book.toml" "mdBook configuration"
check_file ".env" "Environment variables" true

check_directory "client" "Client directory"
check_directory "server" "Server directory"
check_directory "shared" "Shared directory"
check_directory "book" "Documentation source"
check_directory "scripts" "Scripts directory"

echo ""
echo -e "${PURPLE}🚀 Scripts and Executables${NC}"
echo "----------------------------"

# Check scripts
check_file "scripts/setup-docs.sh" "Documentation setup script"
check_file "scripts/build/build-docs.sh" "Documentation build script"
check_file "scripts/deploy-docs.sh" "Documentation deploy script"
check_file "scripts/docs-dev.sh" "Documentation dev script"

# Check if scripts are executable
if [ -f "scripts/setup-docs.sh" ]; then
    if [ -x "scripts/setup-docs.sh" ]; then
        echo -e "Script permissions... ${GREEN}✅ Executable${NC}"
        PASSED_CHECKS=$((PASSED_CHECKS + 1))
    else
        echo -e "Script permissions... ${RED}❌ Not executable${NC}"
        FAILED_CHECKS=$((FAILED_CHECKS + 1))
        echo "  💡 Fix: chmod +x scripts/*.sh"
    fi
    TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
fi

echo ""
echo -e "${PURPLE}🔍 Build Verification${NC}"
echo "--------------------"

# Check if project can be built
echo -n "Checking Rust project compilation... "
if cargo check --quiet >/dev/null 2>&1; then
    echo -e "${GREEN}✅ Passes${NC}"
    PASSED_CHECKS=$((PASSED_CHECKS + 1))
else
    echo -e "${RED}❌ Fails${NC}"
    FAILED_CHECKS=$((FAILED_CHECKS + 1))
    echo "  💡 Run: cargo check for details"
fi
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))

# Check if documentation can be built
if [ -f "book.toml" ] && command_exists "mdbook"; then
    echo -n "Checking documentation compilation... "
    # Capture both stdout and stderr to check for actual errors vs warnings
    build_output=$(mdbook build 2>&1)
    build_exit_code=$?

    # Check if build succeeded (exit code 0) even with warnings
    if [ $build_exit_code -eq 0 ]; then
        echo -e "${GREEN}✅ Passes${NC}"
        PASSED_CHECKS=$((PASSED_CHECKS + 1))
        # Show warnings if any
        if echo "$build_output" | grep -q "WARN\|WARNING"; then
            echo "  ⚠️  Build succeeded with warnings"
        fi
    else
        echo -e "${RED}❌ Fails${NC}"
        FAILED_CHECKS=$((FAILED_CHECKS + 1))
        echo "  💡 Run: mdbook build for details"
    fi
    TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
fi

echo ""
echo -e "${PURPLE}📊 Verification Summary${NC}"
echo "======================="

echo "Total checks: $TOTAL_CHECKS"
echo -e "Passed: ${GREEN}$PASSED_CHECKS${NC}"
echo -e "Failed: ${RED}$FAILED_CHECKS${NC}"
echo -e "Warnings: ${YELLOW}$WARNINGS${NC}"

# Calculate success rate
if [ $TOTAL_CHECKS -gt 0 ]; then
    success_rate=$((PASSED_CHECKS * 100 / TOTAL_CHECKS))
    echo "Success rate: ${success_rate}%"
fi

echo ""

# Final result
if [ $FAILED_CHECKS -eq 0 ]; then
    echo -e "${GREEN}🎉 All essential checks passed!${NC}"

    if [ $WARNINGS -gt 0 ]; then
        echo -e "${YELLOW}ℹ️  Some optional components are missing, but the system should work.${NC}"
    fi

    echo ""
    echo -e "${BLUE}🚀 Quick Start Commands:${NC}"
    echo "  • Start development: just dev"
    echo "  • Start documentation: just docs-dev"
    echo "  • Build documentation: just docs-build"
    echo "  • Show all commands: just help"
    echo ""
    echo -e "${GREEN}✨ You're ready to start developing with Rustelo!${NC}"

    exit 0
else
    echo -e "${RED}❌ $FAILED_CHECKS critical issues found.${NC}"
    echo ""
    echo -e "${BLUE}🔧 Quick Fixes:${NC}"

    # Provide quick fix suggestions
    if ! command_exists "rustc" || ! command_exists "cargo"; then
        echo "  • Install Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
    fi

    if ! command_exists "node"; then
        echo "  • Install Node.js: https://nodejs.org/"
    fi

    if ! command_exists "mdbook"; then
        echo "  • Install mdBook: cargo install mdbook"
    fi

    if ! command_exists "just"; then
        echo "  • Install Just: cargo install just"
    fi

    if [ -f "scripts/setup-docs.sh" ] && [ ! -x "scripts/setup-docs.sh" ]; then
        echo "  • Fix script permissions: chmod +x scripts/*.sh"
    fi

    echo ""
    echo -e "${BLUE}💡 Automated Setup:${NC}"
    echo "  • Run the installer: ./scripts/install.sh"
    echo "  • Setup documentation: ./scripts/setup-docs.sh --full"
    echo ""
    echo -e "${YELLOW}After fixing issues, run this script again to verify.${NC}"

    exit 1
fi
