#!/bin/bash
#
# Archipelago Complete ISO Build System
# =====================================
# 
# This script builds a complete, flashable ISO from source with one command.
# It handles backend compilation, frontend bundling, and ISO creation.
#
# Usage:
#   ./build-iso-complete.sh [options]
#
# Options:
#   --local          Build everything locally (requires Rust + Node.js)
#   --remote HOST    Build on remote server (recommended for ARM -> x86 cross-compile)
#   --skip-backend   Skip backend compilation (use existing binary)
#   --skip-frontend  Skip frontend build (use existing dist)
#   --clean          Clean all build artifacts before building
#   --help           Show this help message
#
# Examples:
#   ./build-iso-complete.sh --remote archipelago@192.168.1.228
#   ./build-iso-complete.sh --local --clean
#
# Auto-installer from live server: when using --remote HOST, the ISO script
# (build-auto-installer-iso.sh) is run with DEV_SERVER=HOST so it captures
# backend, frontend, and container images from that host. Alternatively run
#   DEV_SERVER=archipelago@192.168.1.228 ./image-recipe/build-auto-installer-iso.sh
# to build the auto-installer ISO with live capture only (no backend/frontend build).
#

set -e  # Exit on error

# =============================================================================
# Configuration
# =============================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="$SCRIPT_DIR/image-recipe/build"
BACKEND_SRC="$SCRIPT_DIR/core/archipelago"
FRONTEND_SRC="$SCRIPT_DIR/neode-ui"
ISO_SCRIPT="$SCRIPT_DIR/image-recipe/build-auto-installer-iso.sh"

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

# Build options (defaults)
BUILD_MODE="remote"
REMOTE_HOST=""
SKIP_BACKEND=false
SKIP_FRONTEND=false
CLEAN_BUILD=false

# =============================================================================
# Helper Functions
# =============================================================================

print_header() {
    echo ""
    echo -e "${BLUE}╔════════════════════════════════════════════════════════╗${NC}"
    echo -e "${BLUE}║${NC}  $1"
    echo -e "${BLUE}╚════════════════════════════════════════════════════════╝${NC}"
    echo ""
}

print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

print_error() {
    echo -e "${RED}❌ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

print_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

show_help() {
    head -n 25 "$0" | grep "^#" | sed 's/^# //' | sed 's/^#//'
    exit 0
}

check_command() {
    if ! command -v "$1" &> /dev/null; then
        print_error "$1 is not installed"
        return 1
    fi
    return 0
}

# =============================================================================
# Parse Arguments
# =============================================================================

while [[ $# -gt 0 ]]; do
    case $1 in
        --local)
            BUILD_MODE="local"
            shift
            ;;
        --remote)
            BUILD_MODE="remote"
            REMOTE_HOST="$2"
            shift 2
            ;;
        --skip-backend)
            SKIP_BACKEND=true
            shift
            ;;
        --skip-frontend)
            SKIP_FRONTEND=true
            shift
            ;;
        --clean)
            CLEAN_BUILD=true
            shift
            ;;
        --help|-h)
            show_help
            ;;
        *)
            print_error "Unknown option: $1"
            show_help
            ;;
    esac
done

# =============================================================================
# Pre-flight Checks
# =============================================================================

print_header "Archipelago Complete ISO Builder"

print_info "Build mode: $BUILD_MODE"
[[ -n "$REMOTE_HOST" ]] && print_info "Remote host: $REMOTE_HOST"
[[ "$SKIP_BACKEND" = true ]] && print_warning "Skipping backend build"
[[ "$SKIP_FRONTEND" = true ]] && print_warning "Skipping frontend build"
[[ "$CLEAN_BUILD" = true ]] && print_warning "Clean build enabled"

echo ""

# Check for required commands
if [[ "$BUILD_MODE" == "remote" ]] && [[ -z "$REMOTE_HOST" ]]; then
    print_error "Remote build mode requires --remote HOST"
    exit 1
fi

if [[ "$BUILD_MODE" == "remote" ]]; then
    if ! check_command ssh; then
        exit 1
    fi
    if ! check_command rsync; then
        exit 1
    fi
fi

# =============================================================================
# Step 1: Clean Build Artifacts (if requested)
# =============================================================================

if [[ "$CLEAN_BUILD" = true ]]; then
    print_header "Cleaning Build Artifacts"
    
    if [[ "$SKIP_BACKEND" = false ]]; then
        print_info "Cleaning backend..."
        rm -rf "$BACKEND_SRC/target"
        print_success "Backend cleaned"
    fi
    
    if [[ "$SKIP_FRONTEND" = false ]]; then
        print_info "Cleaning frontend..."
        rm -rf "$FRONTEND_SRC/dist"
        rm -rf "$FRONTEND_SRC/node_modules/.vite"
        print_success "Frontend cleaned"
    fi
    
    print_info "Cleaning ISO build directory..."
    rm -rf "$BUILD_DIR"
    rm -rf "$SCRIPT_DIR/image-recipe/iso-workdir"
    rm -rf "$SCRIPT_DIR/image-recipe/results"
    print_success "ISO build artifacts cleaned"
fi

# =============================================================================
# Step 2: Build Backend
# =============================================================================

if [[ "$SKIP_BACKEND" = false ]]; then
    print_header "Building Backend (Rust)"
    
    if [[ "$BUILD_MODE" == "local" ]]; then
        print_info "Building backend locally..."
        cd "$BACKEND_SRC"
        
        if ! check_command cargo; then
            print_error "Rust/Cargo not installed. Install from: https://rustup.rs"
            exit 1
        fi
        
        cargo build --release
        
        # Copy to build directory
        mkdir -p "$BUILD_DIR/backend"
        cp target/release/archipelago "$BUILD_DIR/backend/"
        chmod +x "$BUILD_DIR/backend/archipelago"
        
        print_success "Backend built locally"
        
    elif [[ "$BUILD_MODE" == "remote" ]]; then
        print_info "Building backend on remote server: $REMOTE_HOST"
        
        # Sync source code to remote
        print_info "Syncing source code to remote..."
        ssh "$REMOTE_HOST" "mkdir -p ~/archy-build"
        rsync -az --delete \
            --exclude 'target/' \
            --exclude 'node_modules/' \
            --exclude '.git/' \
            "$BACKEND_SRC/" "$REMOTE_HOST:~/archy-build/core/archipelago/"
        
        # Build on remote
        print_info "Compiling backend on remote..."
        ssh "$REMOTE_HOST" "cd ~/archy-build/core/archipelago && cargo build --release"
        
        # Copy binary back
        mkdir -p "$BUILD_DIR/backend"
        print_info "Copying binary back to local..."
        scp "$REMOTE_HOST:~/archy-build/core/archipelago/target/release/archipelago" "$BUILD_DIR/backend/"
        chmod +x "$BUILD_DIR/backend/archipelago"
        
        print_success "Backend built on remote server"
    fi
    
    # Verify binary
    if [[ ! -f "$BUILD_DIR/backend/archipelago" ]]; then
        print_error "Backend binary not found after build!"
        exit 1
    fi
    
    BINARY_SIZE=$(du -h "$BUILD_DIR/backend/archipelago" | awk '{print $1}')
    print_success "Backend binary ready ($BINARY_SIZE)"
else
    print_warning "Skipping backend build (using existing binary)"
    if [[ ! -f "$BUILD_DIR/backend/archipelago" ]]; then
        print_error "No existing backend binary found at $BUILD_DIR/backend/archipelago"
        exit 1
    fi
fi

# =============================================================================
# Step 3: Build Frontend
# =============================================================================

if [[ "$SKIP_FRONTEND" = false ]]; then
    print_header "Building Frontend (Vue.js)"
    
    cd "$FRONTEND_SRC"
    
    if ! check_command npm; then
        print_error "Node.js/npm not installed. Install from: https://nodejs.org"
        exit 1
    fi
    
    # Install dependencies if needed
    if [[ ! -d "node_modules" ]] || [[ "$CLEAN_BUILD" = true ]]; then
        print_info "Installing dependencies..."
        npm install
    fi
    
    # Build frontend
    print_info "Building frontend..."
    npm run build
    
    # Copy to build directory
    mkdir -p "$BUILD_DIR/frontend"
    cp -r dist/* "$BUILD_DIR/frontend/"
    
    print_success "Frontend built"
    
    # Verify dist
    if [[ ! -d "$BUILD_DIR/frontend" ]] || [[ -z "$(ls -A "$BUILD_DIR/frontend")" ]]; then
        print_error "Frontend build directory is empty!"
        exit 1
    fi
    
    DIST_SIZE=$(du -sh "$BUILD_DIR/frontend" | awk '{print $1}')
    print_success "Frontend assets ready ($DIST_SIZE)"
else
    print_warning "Skipping frontend build (using existing dist)"
    if [[ ! -d "$BUILD_DIR/frontend" ]] || [[ -z "$(ls -A "$BUILD_DIR/frontend")" ]]; then
        print_error "No existing frontend build found at $BUILD_DIR/frontend"
        exit 1
    fi
fi

# =============================================================================
# Step 4: Build ISO
# =============================================================================

print_header "Building Bootable ISO"

# Check if running on remote or need to transfer
if [[ "$BUILD_MODE" == "remote" ]]; then
    print_info "Transferring build artifacts to remote server..."
    
    # Sync entire project to remote
    ssh "$REMOTE_HOST" "mkdir -p ~/archy"
    rsync -az --delete \
        --exclude '.git/' \
        --exclude 'node_modules/' \
        --exclude 'core/target/' \
        --exclude 'core/parmanode/' \
        "$SCRIPT_DIR/" "$REMOTE_HOST:~/archy/"
    
    print_success "Files synced to remote"
    
    print_info "Running ISO build on remote server (auto-installer, DEV_SERVER=$REMOTE_HOST)..."
    ssh -t "$REMOTE_HOST" "cd ~/archy/image-recipe && DEV_SERVER=$REMOTE_HOST sudo -E bash build-auto-installer-iso.sh" || {
        print_error "ISO build failed on remote server"
        exit 1
    }
    
    print_success "ISO built on remote server"
    
    # Copy ISO back to local
    ISO_NAME="archipelago-installer-x86_64.iso"
    print_info "Copying ISO back to local machine..."
    mkdir -p "$SCRIPT_DIR/image-recipe/results"
    scp "$REMOTE_HOST:~/archy/image-recipe/results/$ISO_NAME" "$SCRIPT_DIR/image-recipe/results/"
    
    ISO_PATH="$SCRIPT_DIR/image-recipe/results/$ISO_NAME"
    
else
    # Local build
    print_info "Running ISO build locally (auto-installer)..."
    cd "$SCRIPT_DIR/image-recipe"
    sudo bash build-auto-installer-iso.sh
    
    ISO_PATH="$SCRIPT_DIR/image-recipe/results/archipelago-installer-x86_64.iso"
fi

# =============================================================================
# Step 5: Verify and Report
# =============================================================================

print_header "Build Complete!"

if [[ -f "$ISO_PATH" ]]; then
    ISO_SIZE=$(du -h "$ISO_PATH" | awk '{print $1}')
    ISO_MD5=$(md5 -q "$ISO_PATH" 2>/dev/null || md5sum "$ISO_PATH" | awk '{print $1}')
    
    echo ""
    echo -e "${GREEN}✅ ISO ready for flashing!${NC}"
    echo ""
    echo -e "  📀 ${BLUE}ISO:${NC}      $ISO_PATH"
    echo -e "  📏 ${BLUE}Size:${NC}     $ISO_SIZE"
    echo -e "  🔐 ${BLUE}MD5:${NC}      $ISO_MD5"
    echo ""
    echo -e "${YELLOW}Next steps:${NC}"
    echo ""
    echo "  1. Insert USB drive"
    echo "  2. Find device: ${BLUE}diskutil list${NC}"
    echo "  3. Flash ISO:"
    echo ""
    echo "     ${BLUE}cd image-recipe && ./write-usb-dd.sh /dev/diskN${NC}"
    echo ""
    echo "  4. Boot from USB on target device"
    echo ""
    
    # Create a flash script for convenience
    cat > "$SCRIPT_DIR/flash-to-usb.sh" <<'FLASH_EOF'
#!/bin/bash
# Quick USB flash script
cd "$(dirname "$0")/image-recipe" && ./write-usb-dd.sh "$@"
FLASH_EOF
    chmod +x "$SCRIPT_DIR/flash-to-usb.sh"
    
    print_success "Created convenience script: ./flash-to-usb.sh"
    
else
    print_error "ISO not found at expected location: $ISO_PATH"
    exit 1
fi

# =============================================================================
# Done!
# =============================================================================

echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║  🎉 Build Complete - Ready to Flash!                  ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════╝${NC}"
echo ""
