#!/bin/bash
#
# ROA2WEB Linux Deployment Script
# Builds and deploys to Windows IIS server via SSH/SCP
#
# Usage:
#   ./deploy.sh              # Full deploy (frontend + backend)
#   ./deploy.sh frontend     # Frontend only
#   ./deploy.sh backend      # Backend only
#   ./deploy.sh test         # Test SSH connection only
#

set -e

# =============================================================================
# CONFIGURATION
# =============================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

# SSH Configuration (matches deploy-config.json)
SSH_HOST="roa2web-prod"  # Uses ~/.ssh/config
REMOTE_PATH="C:/Temp"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# =============================================================================
# HELPER FUNCTIONS
# =============================================================================

log_step() {
    echo -e "\n${CYAN}[*] $1${NC}" >&2
}

log_success() {
    echo -e "${GREEN}    [OK] $1${NC}" >&2
}

log_error() {
    echo -e "${RED}    [ERROR] $1${NC}" >&2
}

log_warning() {
    echo -e "${YELLOW}    [WARN] $1${NC}" >&2
}

log_info() {
    echo -e "    [INFO] $1" >&2
}

# =============================================================================
# SSH CONNECTION TEST
# =============================================================================

test_ssh_connection() {
    log_step "Testing SSH connection to $SSH_HOST..."

    if ssh -o ConnectTimeout=10 "$SSH_HOST" "echo 'Connection successful'" 2>/dev/null; then
        log_success "SSH connection working"
        return 0
    else
        log_error "SSH connection failed"
        echo ""
        echo "Please ensure:"
        echo "  1. SSH key is configured in ~/.ssh/config"
        echo "  2. Public key is added to server's authorized_keys"
        echo "  3. Server is reachable on port 22122"
        echo ""
        echo "SSH config should contain:"
        echo "  Host roa2web-prod"
        echo "      HostName 10.0.20.36"
        echo "      Port 22122"
        echo "      User Administrator"
        echo "      IdentityFile ~/.ssh/roa2web_deploy"
        return 1
    fi
}

# =============================================================================
# BUILD FRONTEND
# =============================================================================

build_frontend() {
    log_step "Building frontend..."

    cd "$PROJECT_ROOT"

    # Check Node.js
    if ! command -v node &> /dev/null; then
        log_error "Node.js not found. Please install Node.js 16+"
        exit 1
    fi

    NODE_VERSION=$(node --version)
    log_info "Node.js: $NODE_VERSION"

    # Check if node_modules exists
    if [ ! -d "node_modules" ]; then
        log_step "Installing npm dependencies..."
        npm install
    fi

    # Build production
    log_step "Running production build..."
    NODE_ENV=production npm run build

    if [ ! -d "dist" ]; then
        log_error "Build failed: dist/ directory not created"
        exit 1
    fi

    # Count files
    FILE_COUNT=$(find dist -type f | wc -l)
    TOTAL_SIZE=$(du -sh dist | cut -f1)
    log_success "Build completed: $FILE_COUNT files ($TOTAL_SIZE)"

    # Verify web.config
    if [ -f "dist/web.config" ]; then
        log_success "web.config present in build"
    else
        log_warning "web.config NOT found in build"
    fi
}

# =============================================================================
# CREATE DEPLOYMENT PACKAGE
# =============================================================================

create_package() {
    local COMPONENT=$1
    local TIMESTAMP=$(date +%Y%m%d-%H%M%S)
    local PACKAGE_DIR="$PROJECT_ROOT/deploy-package-$TIMESTAMP"

    log_step "Creating deployment package..."
    log_info "Package: $PACKAGE_DIR"

    mkdir -p "$PACKAGE_DIR"

    # Frontend
    if [ "$COMPONENT" = "all" ] || [ "$COMPONENT" = "frontend" ]; then
        log_step "Packaging frontend..."
        mkdir -p "$PACKAGE_DIR/frontend"
        cp -r "$PROJECT_ROOT/dist/"* "$PACKAGE_DIR/frontend/"
        log_success "Frontend packaged"
    fi

    # Backend
    if [ "$COMPONENT" = "all" ] || [ "$COMPONENT" = "backend" ]; then
        log_step "Packaging backend..."
        mkdir -p "$PACKAGE_DIR/backend"

        # Copy backend files (excluding venv, __pycache__, logs, .env)
        rsync -av --progress \
            --exclude 'venv' \
            --exclude '__pycache__' \
            --exclude '*.pyc' \
            --exclude '*.pyo' \
            --exclude '.pytest_cache' \
            --exclude 'logs' \
            --exclude '.env' \
            --exclude '.env.local' \
            --exclude '*.log' \
            "$PROJECT_ROOT/backend/" "$PACKAGE_DIR/backend/"

        # Copy .env.example if exists
        if [ -f "$PROJECT_ROOT/backend/.env.example" ]; then
            cp "$PROJECT_ROOT/backend/.env.example" "$PACKAGE_DIR/backend/"
        fi

        log_success "Backend packaged"
    fi

    # Shared modules
    if [ "$COMPONENT" = "all" ] || [ "$COMPONENT" = "backend" ]; then
        log_step "Packaging shared modules..."
        mkdir -p "$PACKAGE_DIR/shared"

        rsync -av --progress \
            --exclude '__pycache__' \
            --exclude '*.pyc' \
            --exclude 'tests' \
            "$PROJECT_ROOT/shared/" "$PACKAGE_DIR/shared/"

        log_success "Shared modules packaged"
    fi

    # Config templates
    log_step "Packaging config templates..."
    if [ -d "$PROJECT_ROOT/deployment/config" ]; then
        mkdir -p "$PACKAGE_DIR/config"
        cp -r "$PROJECT_ROOT/deployment/config/"* "$PACKAGE_DIR/config/" 2>/dev/null || true
    fi

    # Deployment scripts
    log_step "Packaging deployment scripts..."
    mkdir -p "$PACKAGE_DIR/scripts"

    SCRIPTS=(
        "ROA2WEB-Console.ps1"
        "Install-ROA2WEB.ps1"
        "Check-And-Deploy.ps1"
    )

    for script in "${SCRIPTS[@]}"; do
        if [ -f "$PROJECT_ROOT/deployment/windows/scripts/$script" ]; then
            cp "$PROJECT_ROOT/deployment/windows/scripts/$script" "$PACKAGE_DIR/scripts/"
        fi
    done

    log_success "Deployment scripts packaged"

    # Create README
    cat > "$PACKAGE_DIR/README.txt" << EOF
================================================================================
                        ROA2WEB DEPLOYMENT PACKAGE
                    Generated: $(date '+%Y-%m-%d %H:%M:%S')
                    From: Linux/LXC deployment script
================================================================================

CONTENTS:
---------
  backend/      Unified FastAPI backend
  frontend/     Vue.js SPA (production build)
  shared/       Shared Python modules
  config/       Configuration templates
  scripts/      PowerShell deployment scripts

DEPLOYMENT:
-----------
Server will auto-deploy within 5 minutes (Check-And-Deploy.ps1 scheduled task)

Or manually:
  cd scripts
  .\ROA2WEB-Console.ps1 -NonInteractive -Action DeployAll

================================================================================
EOF

    # Calculate package size
    PACKAGE_SIZE=$(du -sh "$PACKAGE_DIR" | cut -f1)
    FILE_COUNT=$(find "$PACKAGE_DIR" -type f | wc -l)

    log_success "Package created: $FILE_COUNT files ($PACKAGE_SIZE)"

    # Return path via global variable (avoid stdout pollution from rsync)
    CREATED_PACKAGE_DIR="$PACKAGE_DIR"
}

# =============================================================================
# TRANSFER TO SERVER
# =============================================================================

transfer_to_server() {
    local PACKAGE_DIR=$1
    local TIMESTAMP=$(date +%Y%m%d-%H%M%S)
    local REMOTE_DEPLOY_DIR="deploy-$TIMESTAMP"
    local REMOTE_FULL_PATH="C:\\Temp\\$REMOTE_DEPLOY_DIR"

    log_step "Transferring to server..."
    log_info "Remote path: C:\\Temp\\$REMOTE_DEPLOY_DIR"

    # Create remote directory
    log_step "Creating remote directory..."
    ssh "$SSH_HOST" "New-Item -ItemType Directory -Path 'C:\\Temp\\$REMOTE_DEPLOY_DIR' -Force"
    log_success "Remote directory created"

    # Transfer files one directory at a time (Bitvise SCP compatibility)
    log_step "Uploading files via SCP..."

    for dir in "$PACKAGE_DIR"/*/; do
        if [ -d "$dir" ]; then
            local dirname=$(basename "$dir")
            log_info "Uploading $dirname/..."
            scp -r "$dir" "roa2web-prod:C:\\Temp\\$REMOTE_DEPLOY_DIR\\$dirname"
        fi
    done

    # Upload root files (README, etc.)
    for file in "$PACKAGE_DIR"/*; do
        if [ -f "$file" ]; then
            local filename=$(basename "$file")
            scp "$file" "roa2web-prod:C:\\Temp\\$REMOTE_DEPLOY_DIR\\$filename"
        fi
    done

    log_success "Transfer completed"

    # Verify transfer
    log_step "Verifying transfer..."
    REMOTE_FILE_COUNT=$(ssh "$SSH_HOST" "(Get-ChildItem -Path 'C:\\Temp\\$REMOTE_DEPLOY_DIR' -Recurse -File).Count")
    log_success "Remote files: $REMOTE_FILE_COUNT"

    echo ""
    echo "=========================================="
    echo -e "${GREEN}  DEPLOYMENT PACKAGE UPLOADED${NC}"
    echo "=========================================="
    echo ""
    echo "  Remote path: C:\\Temp\\$REMOTE_DEPLOY_DIR"
    echo ""
    echo "  Server will auto-deploy within 5 minutes."
    echo "  Or manually deploy:"
    echo "    ssh $SSH_HOST"
    echo "    cd C:\\Temp\\$REMOTE_DEPLOY_DIR\\scripts"
    echo "    .\\ROA2WEB-Console.ps1"
    echo ""
}

# =============================================================================
# CLEANUP
# =============================================================================

cleanup_local_package() {
    local PACKAGE_DIR=$1

    log_step "Cleaning up local package..."
    rm -rf "$PACKAGE_DIR"
    log_success "Local package removed"
}

# =============================================================================
# MAIN
# =============================================================================

main() {
    local COMPONENT=${1:-all}

    echo ""
    echo "========================================"
    echo "  ROA2WEB Linux Deployment Script"
    echo "  Component: $COMPONENT"
    echo "========================================"
    echo ""

    # Handle test command
    if [ "$COMPONENT" = "test" ]; then
        test_ssh_connection
        exit $?
    fi

    # Validate component
    case $COMPONENT in
        all|frontend|backend)
            ;;
        *)
            echo "Usage: $0 [all|frontend|backend|test]"
            exit 1
            ;;
    esac

    # Test SSH connection first
    if ! test_ssh_connection; then
        exit 1
    fi

    # Build frontend if needed
    if [ "$COMPONENT" = "all" ] || [ "$COMPONENT" = "frontend" ]; then
        build_frontend
    fi

    # Create package (sets CREATED_PACKAGE_DIR global variable)
    create_package "$COMPONENT"

    # Transfer to server
    transfer_to_server "$CREATED_PACKAGE_DIR"

    # Cleanup
    cleanup_local_package "$CREATED_PACKAGE_DIR"

    echo ""
    echo -e "${GREEN}Deployment completed successfully!${NC}"
    echo ""
}

# Run main with all arguments
main "$@"
