#!/bin/bash
# End-to-end bootstrap integration test
# Tests the complete bootstrap flow from CLI

set -e

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

# Test configuration
TEST_DIR="/tmp/nip-e2e-test-$$"
NIP_BIN="../nip"
TESTS_PASSED=0
TESTS_FAILED=0

# Logging functions
log_info() {
    echo -e "${BLUE}ℹ${NC} $1"
}

log_success() {
    echo -e "${GREEN}✅${NC} $1"
    ((TESTS_PASSED++)) || true
}

log_error() {
    echo -e "${RED}❌${NC} $1"
    ((TESTS_FAILED++)) || true
}

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

# Setup test environment
setup_test_env() {
    log_info "Setting up test environment..."

    # Create test directory
    mkdir -p "$TEST_DIR"
    mkdir -p "$TEST_DIR/.nip/bootstrap"
    mkdir -p "$TEST_DIR/.nip/cache"

    # Set HOME to test directory for isolation
    export HOME="$TEST_DIR"
    export NIP_HOME="$TEST_DIR/.nip"

    log_success "Test environment ready: $TEST_DIR"
}

# Cleanup test environment
cleanup_test_env() {
    log_info "Cleaning up test environment..."
    if [ -d "$TEST_DIR" ]; then
        rm -rf "$TEST_DIR"
    fi
    log_success "Cleanup complete"
}

# Check if NIP binary exists
check_nip_binary() {
    log_info "Checking NIP binary..."

    if [ ! -f "$NIP_BIN" ]; then
        log_error "NIP binary not found at $NIP_BIN"
        log_info "Please build NIP first: nim c nip.nim"
        exit 1
    fi

    log_success "NIP binary found"
}

# Test: NIP version
test_nip_version() {
    log_info "Test: NIP version command"

    if $NIP_BIN --version &>/dev/null; then
        log_success "NIP version command works"
    else
        log_error "NIP version command failed"
    fi
}

# Test: Bootstrap list (empty)
test_bootstrap_list_empty() {
    log_info "Test: Bootstrap list (should be empty)"

    output=$($NIP_BIN bootstrap list 2>&1 || true)

    if echo "$output" | grep -q "No bootstrap tools installed"; then
        log_success "Bootstrap list shows empty correctly"
    else
        log_warning "Bootstrap list output unexpected (may have system tools)"
    fi
}

# Test: Bootstrap info for non-installed tool
test_bootstrap_info_not_installed() {
    log_info "Test: Bootstrap info for non-installed tool"

    output=$($NIP_BIN bootstrap info gentoo 2>&1 || true)

    if echo "$output" | grep -q "not installed\|Not found"; then
        log_success "Bootstrap info correctly reports not installed"
    else
        log_warning "Bootstrap info output unexpected"
    fi
}

# Test: Bootstrap recipes list
test_bootstrap_recipes() {
    log_info "Test: Bootstrap recipes list"

    if $NIP_BIN bootstrap recipes &>/dev/null; then
        log_success "Bootstrap recipes command works"
    else
        log_warning "Bootstrap recipes command failed (may need network)"
    fi
}

# Test: Recipe validation
test_recipe_validation() {
    log_info "Test: Recipe validation"

    # Check if recipes exist
    if [ -d "recipes" ]; then
        for recipe in recipes/*/minimal-*.kdl; do
            if [ -f "$recipe" ]; then
                log_info "Validating recipe: $recipe"
                if $NIP_BIN bootstrap validate "$recipe" &>/dev/null; then
                    log_success "Recipe validation passed: $(basename $recipe)"
                else
                    log_error "Recipe validation failed: $(basename $recipe)"
                fi
            fi
        done
    else
        log_warning "Recipes directory not found, skipping validation"
    fi
}

# Test: Bootstrap help
test_bootstrap_help() {
    log_info "Test: Bootstrap help command"

    output=$($NIP_BIN bootstrap help 2>&1 || true)

    if echo "$output" | grep -q "list\|install\|remove"; then
        log_success "Bootstrap help shows commands"
    else
        log_error "Bootstrap help output incomplete"
    fi
}

# Test: Build command with missing tools (dry run)
test_build_missing_tools() {
    log_info "Test: Build with missing tools (detection)"

    # This should detect missing tools and offer options
    # We'll just check if it doesn't crash
    output=$($NIP_BIN build vim --source=gentoo --dry-run 2>&1 || true)

    if echo "$output" | grep -q "Gentoo\|not found\|bootstrap"; then
        log_success "Build correctly detects missing tools"
    else
        log_warning "Build tool detection output unexpected"
    fi
}

# Test: Container runtime detection
test_container_detection() {
    log_info "Test: Container runtime detection"

    if command -v podman &>/dev/null; then
        log_success "Podman detected"
    elif command -v docker &>/dev/null; then
        log_success "Docker detected"
    else
        log_warning "No container runtime detected (optional)"
    fi
}

# Test: Recipe update (if network available)
test_recipe_update() {
    log_info "Test: Recipe update"

    # Try to update recipes (may fail without network)
    if $NIP_BIN bootstrap update-recipes &>/dev/null; then
        log_success "Recipe update successful"
    else
        log_warning "Recipe update failed (may need network)"
    fi
}

# Test: Bootstrap installation scripts exist
test_installation_scripts() {
    log_info "Test: Installation scripts exist"

    local scripts_found=0

    for tool in nix pkgsrc gentoo; do
        if [ -d "recipes/$tool/scripts" ]; then
            if [ -f "recipes/$tool/scripts/install.sh" ] || \
               [ -f "recipes/$tool/scripts/bootstrap.sh" ]; then
                ((scripts_found++))
            fi
        fi
    done

    if [ $scripts_found -ge 2 ]; then
        log_success "Installation scripts found for $scripts_found tools"
    else
        log_error "Installation scripts missing"
    fi
}

# Test: Verification scripts exist
test_verification_scripts() {
    log_info "Test: Verification scripts exist"

    local scripts_found=0

    for tool in nix pkgsrc gentoo; do
        if [ -f "recipes/$tool/scripts/verify.sh" ]; then
            ((scripts_found++))
        fi
    done

    if [ $scripts_found -ge 2 ]; then
        log_success "Verification scripts found for $scripts_found tools"
    else
        log_error "Verification scripts missing"
    fi
}

# Test: Recipe schema exists
test_recipe_schema() {
    log_info "Test: Recipe schema exists"

    if [ -f "recipes/schema/recipe.json" ]; then
        log_success "Recipe schema found"
    else
        log_error "Recipe schema not found"
    fi
}

# Test: Documentation exists
test_documentation() {
    log_info "Test: Documentation exists"

    local docs_found=0
    local required_docs=(
        "nip/docs/getting-started.md"
        "nip/docs/bootstrap-guide.md"
        "nip/docs/bootstrap-overview.md"
        "nip/docs/bootstrap-detection-flow.md"
        "nip/docs/quick-reference.md"
    )

    for doc in "${required_docs[@]}"; do
        if [ -f "$doc" ]; then
            ((docs_found++))
        fi
    done

    if [ $docs_found -eq ${#required_docs[@]} ]; then
        log_success "All required documentation found"
    else
        log_error "Missing documentation: $((${#required_docs[@]} - docs_found)) files"
    fi
}

# Print test summary
print_summary() {
    echo ""
    echo "======================================"
    echo "TEST SUMMARY"
    echo "======================================"
    echo -e "Total tests: $((TESTS_PASSED + TESTS_FAILED))"
    echo -e "${GREEN}Passed: $TESTS_PASSED${NC}"
    echo -e "${RED}Failed: $TESTS_FAILED${NC}"
    echo "======================================"

    if [ $TESTS_FAILED -eq 0 ]; then
        echo -e "${GREEN}✅ All tests passed!${NC}"
        return 0
    else
        echo -e "${RED}❌ Some tests failed${NC}"
        return 1
    fi
}

# Main test execution
main() {
    echo "NIP Bootstrap End-to-End Tests"
    echo "==============================="
    echo ""

    # Setup
    setup_test_env
    check_nip_binary

    # Run tests
    test_nip_version
    test_bootstrap_list_empty
    test_bootstrap_info_not_installed
    test_bootstrap_recipes
    test_recipe_validation
    test_bootstrap_help
    test_build_missing_tools
    test_container_detection
    test_recipe_update
    test_installation_scripts
    test_verification_scripts
    test_recipe_schema
    test_documentation

    # Cleanup and summary
    cleanup_test_env
    print_summary
}

# Trap errors
trap 'log_error "Test script failed at line $LINENO"' ERR

# Run main
main
exit $?
