#!/bin/bash
# TSID Initial Setup Script for Ubuntu/Debian
# Run after: sudo apt-get install tsid-client
# Usage: sudo tsid-setup [--force]
#
# This script performs:
#   1. Company code input -> Device registration (TSID server)
#   2. Emergency PIN setup
#   3. System file backup
#   4. PAM/SSH/NSS configuration changes
#   5. LightDM installation and GDM->LightDM switch
#   6. Installation verification
#   7. SSH/Display Manager restart
#
# apt-get install stage doesn't change system settings,
# so existing login system remains intact until this script runs.

# set -e intentionally omitted: recovery needed on failure

# Set locale
export LANG=C.UTF-8
export LC_ALL=C.UTF-8

# Clear all TSID environment variables to force interactive input
unset TSID_COMPANY_CODE
unset TSID_EMERGENCY_PIN

# Load TSID postinst functions
SCRIPT_DIR="/usr/share/tsid"
if [ ! -f "$SCRIPT_DIR/postinst_functions.sh" ]; then
    echo "Error: TSID package is not installed."
    echo "Run: sudo apt-get install tsid-client"
    exit 1
fi

# Clear environment variable to force interactive input
unset TSID_COMPANY_CODE

. "$SCRIPT_DIR/postinst_functions.sh"
. "$SCRIPT_DIR/postinst_pam_config.sh"
. "$SCRIPT_DIR/postinst_display_manager.sh"

# Package configuration
PACKAGE_NAME="tsid-client"
CONFIG_DIR="/etc/tsid"
API_URL="https://tpg.tsidcert.com/svr/device"

# Root permission check
if [ "$(id -u)" -ne 0 ]; then
    echo "Error: This script must be run as root (sudo tsid-setup)"
    exit 1
fi

# Installation status check
check_setup_status() {
    local needs_setup=false
    
    if [ ! -f "$CONFIG_DIR/config.conf" ] || ! grep -q "^server_code=" "$CONFIG_DIR/config.conf" 2>/dev/null; then
        needs_setup=true
    fi
    
    if [ ! -f "$CONFIG_DIR/emergency_pin" ]; then
        needs_setup=true
    fi
    
    if [ "$needs_setup" = "true" ]; then
        return 1
    else
        return 0
    fi
}

# Company code input
get_company_code() {
    (
        local company_code=""
        
        # Interactive input with validation loop
        while true; do
            echo "" >&2
            echo "======================================" >&2
            echo " TSID Setup - Company Code" >&2
            echo "======================================" >&2
            echo "" >&2
            echo " Please enter your company code:" >&2
            echo " (This will register this device with TSID server)" >&2
            echo "" >&2
            read -p "Company code: " company_code < /dev/tty
            
            if [ -z "$company_code" ]; then
                echo "[ERROR] Company code cannot be empty" >&2
                echo "Please try again..." >&2
                continue
            fi
            
            # Debug: show what we captured (stderr to avoid interfering with variable assignment)
            echo "[DEBUG] Captured company code: '$company_code'" >&2
            
            # Only output the company code, no extra text
            echo "$company_code"
            break
        done
    )
}

# Device registration
register_device() {
    local company_code="$1"
    local mac_addr=""
    local host_name=""
    local svr_type=""
    local response=""
    
    # Get MAC address
    mac_addr=$(ip link show | grep -E 'link/ether' | head -1 | awk '{print $2}' | tr -d ':')
    if [ -z "$mac_addr" ]; then
        echo "[ERROR] Failed to get MAC address"
        return 1
    fi
    
    # Get hostname
    host_name=$(hostname)
    if [ -z "$host_name" ]; then
        host_name="unknown"
    fi
    
    # Set server type (matching Rocky Linux)
    svr_type="L"
    
    echo "[INFO] Registering device with TSID server..."
    echo "[INFO] MAC address: $mac_addr"
    echo "[INFO] Company code: $company_code"
    echo "[INFO] Hostname: $host_name"
    echo "[INFO] Server type: $svr_type"
    
    # Register device with all required parameters (matching Rocky Linux)
    local request_data="{
        \"company_code\": \"$company_code\",
        \"mac_address\": \"$mac_addr\",
        \"host_name\": \"$host_name\",
        \"svr_type\": \"$svr_type\"
    }"
    
    echo "[DEBUG] Sending request to: $API_URL"
    echo "[DEBUG] Request data: $request_data"
    
    response=$(curl -s -w "%{http_code}" -X POST "$API_URL" \
        -H "Content-Type: application/json" \
        -d "$request_data")
    
    # Extract HTTP code (last 3 digits) and response body
    http_code="${response: -3}"
    response_body="${response%???}"
    
    echo "[DEBUG] HTTP status code: $http_code"
    echo "[DEBUG] Response body: '$response_body'"
    
    if [ "$http_code" = "000" ]; then
        echo "[ERROR] Network connection failed"
        echo "[ERROR] Unable to connect to TSID server"
        echo "[ERROR] Please check:"
        echo "  - Internet connection"
        echo "  - Firewall settings"
        echo "  - DNS resolution"
        return 1
    fi
    
    if [ -z "$response_body" ]; then
        echo "[ERROR] Empty response from TSID server"
        echo "[ERROR] Server may be experiencing issues"
        return 1
    fi
    
    if [ "$http_code" = "400" ]; then
        echo "[ERROR] Invalid company code: '$company_code'"
        echo "[ERROR] Please verify your company code and try again"
        return 1
    fi
    
    if [ "$http_code" = "401" ]; then
        echo "[ERROR] Company code not authorized: '$company_code'"
        echo "[ERROR] Please contact TSID support"
        return 1
    fi
    
    if [ "$http_code" = "404" ]; then
        echo "[ERROR] TSID server endpoint not found"
        echo "[ERROR] Server configuration may have changed"
        return 1
    fi
    
    if [ "$http_code" = "500" ]; then
        echo "[ERROR] TSID server internal error"
        echo "[ERROR] Please try again later or contact support"
        return 1
    fi
    
    if [ "$http_code" != "200" ]; then
        echo "[ERROR] Unexpected server response (HTTP $http_code)"
        echo "[ERROR] Response: $response_body"
        return 1
    fi
    
    # Use response_body for parsing
    response="$response_body"
    
    # Parse response with better error handling
    echo "[DEBUG] Server response: $response"
    
    # Parse server response (matching Rocky Linux behavior)
    local server_code=""
    
    # Parse server_code only (user_code not used in Rocky)
    server_code=$(echo "$response" | grep -o '"server_code":"[^"]*' | cut -d'"' -f4)
    
    echo "[DEBUG] Parsed server_code: '$server_code'"
    
    if [ -z "$server_code" ]; then
        echo "[ERROR] Failed to parse server_code from response"
        echo "[ERROR] Response: $response"
        echo "[ERROR] Please check server response format"
        return 1
    fi
    
    # Save configuration (matching Rocky Linux format)
    mkdir -p "$CONFIG_DIR"
    cat > "$CONFIG_DIR/config.conf" << EOF
# TSID Client Configuration
server_code=$server_code
company_code=$company_code
api_url=https://tpg.tsidcert.com
mac_address=$mac_addr
host_name=$host_name
svr_type=$svr_type
EOF
    chmod 644 "$CONFIG_DIR/config.conf"
    
    echo "[SUCCESS] Device registered successfully"
    echo "[INFO] Server code: $server_code"
    
    return 0
}

# Emergency PIN setup
setup_emergency_pin() {
    local emergency_pin=""
    
    # Interactive input
    echo ""
    echo "======================================"
    echo " TSID Setup - Emergency PIN"
    echo "======================================"
    echo ""
    echo " Please set emergency PIN (4-8 digits):"
    echo " This PIN can be used when mobile authentication fails"
    echo ""
    while true; do
        read -p "Emergency PIN: " emergency_pin < /dev/tty
        if [ -z "$emergency_pin" ]; then
            echo "[ERROR] PIN cannot be empty"
            continue
        fi
        if [ ${#emergency_pin} -lt 4 ] || [ ${#emergency_pin} -gt 8 ]; then
            echo "[ERROR] PIN must be 4-8 digits"
            continue
        fi
        if ! echo "$emergency_pin" | grep -q '^[0-9]\+$'; then
            echo "[ERROR] PIN must contain only digits"
            continue
        fi
        break
    done
    echo ""
    
    # Save emergency PIN
    echo "$emergency_pin" > "$CONFIG_DIR/emergency_pin"
    chmod 600 "$CONFIG_DIR/emergency_pin"
    
    # Verify PIN was saved (without revealing it)
    if [ -f "$CONFIG_DIR/emergency_pin" ] && [ -s "$CONFIG_DIR/emergency_pin" ]; then
        local pin_length=$(wc -c < "$CONFIG_DIR/emergency_pin")
        echo "[DEBUG] Emergency PIN saved (${pin_length} characters) to $CONFIG_DIR/emergency_pin"
        echo "[SUCCESS] Emergency PIN configured"
    else
        echo "[ERROR] Failed to save emergency PIN"
        return 1
    fi
}

# Main setup
main_setup() {
    echo ""
    echo "======================================"
    echo " TSID Setup for Ubuntu/Debian"
    echo "======================================"
    echo ""
    
    # Check if already configured
    if check_setup_status && [ "$1" != "--force" ]; then
        echo "[INFO] TSID is already configured"
        echo "[INFO] Use --force to reconfigure"
        echo ""
        echo "Current configuration:"
        if [ -f "$CONFIG_DIR/config.conf" ]; then
            grep "^server_code=" "$CONFIG_DIR/config.conf" 2>/dev/null || true
        fi
        if [ -f "$CONFIG_DIR/emergency_pin" ]; then
            echo "Emergency PIN: set"
        fi
        echo ""
        return 0
    fi
    
    # Get company code
    if ! company_code=$(get_company_code); then
        echo ""
        echo "======================================"
        echo " TSID Setup Failed"
        echo "======================================"
        echo " Reason: Company code not provided"
        echo ""
        echo " Your system is unchanged."
        echo ""
        echo " Required Actions:"
        echo " 1. Set environment variable:"
        echo "    export TSID_COMPANY_CODE=your_code"
        echo ""
        echo " 2. Or create file:"
        echo "    echo 'your_code' | sudo tee /etc/tsid/company_code"
        echo ""
        echo " 3. Retry setup:"
        echo "    sudo tsid-setup"
        echo "======================================"
        echo ""
        exit 1
    fi
    
    # Register device
    if [ "$1" != "--skip-registration" ]; then
        if ! register_device "$company_code"; then
            echo ""
            echo " Device registration failed."
            echo " Your system is unchanged."
            echo " To retry: sudo tsid-setup"
            echo ""
            echo " For testing: sudo tsid-setup --skip-registration"
            echo ""
            exit 1
        fi
    else
        echo "[WARNING] Skipping device registration for testing"
        # Create dummy config for testing
        mkdir -p "$CONFIG_DIR"
        cat > "$CONFIG_DIR/config.conf" << EOF
# TSID Configuration (testing mode)
server_code=test_server_code
user_code=test_user_code
api_url=$API_URL
EOF
        chmod 600 "$CONFIG_DIR/config.conf"
    fi
    
    # Setup emergency PIN
    setup_emergency_pin
    
    # Apply PAM configuration
    if [ -f "/usr/bin/tsid-setup-pam" ]; then
        log_info "Applying PAM authentication settings..."
        chmod 755 /usr/bin/tsid-setup-pam
        /usr/bin/tsid-setup-pam --setup || true
        log_info "PAM authentication configuration completed."
    else
        log_error "PAM setup script not found: /usr/bin/tsid-setup-pam"
    fi

    # Configure PAM SSH (includes nsswitch.conf NSS setup)
    log_info "Configuring PAM SSH settings..."
    configure_pam_ssh || {
        log_error "PAM SSH configuration failed (nsswitch.conf may not be updated)"
    }
    log_info "PAM SSH configuration completed."
    
    # Configure display manager
    if [ -f "$SCRIPT_DIR/postinst_display_manager.sh" ]; then
        log_info "Configuring display manager..."
        . "$SCRIPT_DIR/postinst_display_manager.sh"
        
        # Detect current display manager
        detect_display_manager
        
        # Configure LightDM (Ubuntu default)
        if command -v lightdm >/dev/null 2>&1; then
            switch_display_manager lightdm || {
                log_error "LightDM configuration failed"
                exit 1
            }
        else
            log_warning "LightDM not found, skipping display manager configuration"
        fi
    fi
    
    # Restart services
    log_info "Restarting services..."
    systemctl daemon-reload >/dev/null 2>&1 || true
    systemctl restart ssh 2>/dev/null || systemctl restart sshd 2>/dev/null || true
    
    # Restart display manager (matching Rocky behavior)
    if command -v lightdm >/dev/null 2>&1; then
        systemctl restart lightdm 2>/dev/null || true
        log_info "Display manager restarted: lightdm"
    fi
    
    # Verify installation
    log_info "Verifying installation..."
    if [ -f "$CONFIG_DIR/config.conf" ] && [ -f "$CONFIG_DIR/emergency_pin" ]; then
        echo ""
        echo "======================================"
        echo " TSID Setup Completed Successfully"
        echo "======================================"
        echo ""
        echo " Configuration files:"
        echo "  - $CONFIG_DIR/config.conf"
        echo "  - $CONFIG_DIR/emergency_pin"
        echo ""
        echo " Next steps:"
        echo "  1. Reboot the system"
        echo "  2. Use mobile app to authenticate"
        echo "  3. Or use emergency PIN if needed"
        echo ""
        echo "======================================"
        echo ""
        return 0
    else
        echo ""
        echo "======================================"
        echo " TSID Setup Failed"
        echo "======================================"
        echo " Configuration files missing"
        echo ""
        exit 1
    fi
}

# Run main setup
main_setup "$@"
