#!/bin/bash
# NIP v0.2.0 "Weihnachtsmann" Bootstrap Installer 🎅✨
# Official installer for NIP - Nexus Integrated Packager
#
# Usage:
#   curl -L https://git.maiwald.work/Nexus/NexusToolKit/raw/branch/main/nip/install.sh | bash
#   wget -O- https://git.maiwald.work/Nexus/NexusToolKit/raw/branch/main/nip/install.sh | bash
#
# Repository: https://git.maiwald.work/Nexus/NexusToolKit
# License: Dual EUPL-1.2/ACUL

set -e

# Configuration
REPO_BASE="https://git.maiwald.work/Nexus/NexusToolKit/raw/branch/main/nip"
VERSION="v0.2.0-weihnachtsmann"
INSTALL_DIR="/usr/local/bin"
BINARY_NAME="nip"

# 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

# Emojis
SANTA="🎅"
ROCKET="🚀"
CHECK="✅"
CROSS="❌"
INFO="ℹ️"
WARN="⚠️"
PACKAGE="📦"
WRENCH="🔧"

echo -e "${PURPLE}${SANTA} NIP ${VERSION} 'Weihnachtsmann' Bootstrap Installer${NC}"
echo -e "${PURPLE}================================================================${NC}"
echo ""
echo -e "${CYAN}${INFO} Official installer for NIP - Nexus Integrated Packager${NC}"
echo -e "${CYAN}${INFO} Repository: https://git.maiwald.work/Nexus/NexusToolKit${NC}"
echo ""

# Function to print colored output
print_status() {
    echo -e "${GREEN}${CHECK} $1${NC}"
}

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

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

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

# Function to detect architecture
detect_arch() {
    local arch=$(uname -m)
    case $arch in
        x86_64|amd64)
            echo "x86_64"
            ;;
        aarch64|arm64)
            echo "aarch64"
            ;;
        armv7l)
            echo "armv7"
            ;;
        riscv64)
            echo "riscv64"
            ;;
        *)
            print_error "Unsupported architecture: $arch"
            exit 1
            ;;
    esac
}

# Function to detect OS
detect_os() {
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        echo "linux"
    elif [[ "$OSTYPE" == "darwin"* ]]; then
        echo "macos"
    elif [[ "$OSTYPE" == "freebsd"* ]]; then
        echo "freebsd"
    elif [[ "$OSTYPE" == "netbsd"* ]]; then
        echo "netbsd"
    elif [[ "$OSTYPE" == "openbsd"* ]]; then
        echo "openbsd"
    else
        print_error "Unsupported OS: $OSTYPE"
        exit 1
    fi
}

# Function to check if running as root
check_root() {
    if [ "$EUID" -ne 0 ]; then
        print_error "This installerquires root privileges"
        echo -e "${YELLOW}${INFO} Please run with sudo:${NC}"
        echo -e "${CYAN}  curl -L https://git.maiwald.work/Nexus/NexusToolKit/raw/branch/main/nip/install.sh | sudo bash${NC}"
        echo -e "${CYAN}  wget -O- https://git.maiwald.work/Nexus/NexusToolKit/raw/branch/main/nip/install.sh | sudo bash${NC}"
        exit 1
    fi
}

# Function to check dependencies
check_dependencies() {
    local missing_deps=()

    if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then
        missing_deps+=("curl or wget")
    fi

    if ! command -v tar >/dev/null 2>&1; then
        missing_deps+=("tar")
    fi

    if [ ${#missing_deps[@]} -ne 0 ]; then
        print_error "Missing required dependencies: ${missing_deps[*]}"
        echo -e "${YELLOW}${INFO} Please install the missing dependencies and try again${NC}"
        exit 1
    fi
}

# Function to download file
download_file() {
    local url="$1"
    local output="$2"

    if command -v curl >/dev/null 2>&1; then
        curl -fsSL "$url" -o "$output"
    elif command -v wget >/dev/null 2>&1; then
        wget -q "$url" -O "$output"
    else
        print_error "Neither curl nor wget available"
        exit 1
    fi
}

# Function to select optimal binary variant
select_variant() {
    local os="$1"
    local arch="$2"

    # For now, we only have Linux x86_64 binaries
    if [[ "$os" != "linux" ]] || [[ "$arch" != "x86_64" ]]; then
        print_error "Pre-built binaries not available for $os/$arch"
        echo -e "${YELLOW}${INFO} Supported platforms: linux/x86_64${NC}"
        echo -e "${YELLOW}${INFO} Please build from source: https://git.maiwald.work/Nexus/NexusToolKit${NC}"
        exit 1
    fi

    # Detect system characteristics for optimal variant selection
    local total_mem=$(grep MemTotal /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
    local is_embedded=false

    # Consider embedded if less than 512MB RAM
    if [ "$total_mem" -lt 524288 ]; then
        is_embedded=true
    fi

    # Check if this looks like a minimal/embedded system
    if [ -f "/etc/alpine-release" ] || [ -f "/etc/busybox" ] || [ "$is_embedded" = true ]; then
        echo "nip-optimized-size-upx"  # 517KB - smallest possible
        print_info "Selected ultra-minimal variant (517KB) for embedded/minimal system"
    else
        echo "nip-static-upx"  # 557KB - good balance
        print_info "Selected compressed variant (557KB) for general use"
    fi
}

# Function to verify binary
verify_binary() {
    local binary_path="$1"

    # Check if file exists and is executable
    if [ ! -f "$binary_path" ]; then
        print_error "Binary not found: $binary_path"
        return 1
    fi

    if [ ! -x "$binary_path" ]; then
        print_error "Binary not executable: $binary_path"
        return 1
    fi

    # Test basic functionality
    if ! "$binary_path" --version >/dev/null 2>&1; then
        print_warning "Binary version check failed (may require setup)"
        return 0  # Not fatal - might need system setup
    fi

    return 0
}

# Function to create system directories
create_directories() {
    print_info "Creating system directories..."

    # Core NIP directories
    mkdir -p /Programs
    mkdir -p /System/Links/{Executables,Libraries,Headers,Shared}
    mkdir -p /var/lib/nip/{cas,db,generations}
    mkdir -p /var/cache/nip/{packages,build}
    mkdir -p /var/log/nip
    mkdir -p /etc/nip

    # Set appropriate permissions
    chmod 755 /Programs /System/Links/*
    chmod 755 /var/lib/nip /var/lib/nip/*
    chmod 755 /var/cache/nip /var/cache/nip/*
    chmod 755 /var/log/nip
    chmod 755 /etc/nip

    print_status "System directories created"
}

# Function to setup system integration
setup_system_integration() {
    print_info "Setting up system integration..."

    # Add NIP to PATH if not already there
    if ! echo "$PATH" | grep -q "$INSTALL_DIR"; then
        echo "export PATH=\"$INSTALL_DIR:\$PATH\"" > /etc/profile.d/nip.sh
        chmod 644 /etc/profile.d/nip.sh
        print_status "Added NIP to system PATH"
    fi

    # Setup library path for NIP-managed libraries
    echo "/System/Links/Libraries" > /etc/ld.so.conf.d/nip.conf
    if command -v ldconfig >/dev/null 2>&1; then
        ldconfig 2>/dev/null || true
        print_status "Updated library cache"
    fi

    print_status "System integration complete"
}

# Main installation function
main() {
    echo -e "${ROCKET} Starting NIP installation..."
    echo ""

    # Pre-flight checks
    check_root
    check_dependencies

    # Detect system
    local os=$(detect_os)
    local arch=$(detect_arch)
    print_info "Detected system: $os/$arch"

    # Select optimal binary variant
    local variant=$(select_variant "$os" "$arch")
    local binary_url="$REPO_BASE/$variant"

    print_info "Downloading NIP binary..."
    print_info "URL: $binary_url"

    # Create temporary directory
    local temp_dir=$(mktemp -d)
    trap "rm -rf $temp_dir" EXIT

    # Download binary
    local temp_binary="$temp_dir/nip"
    if ! download_file "$binary_url" "$temp_binary"; then
        print_error "Failed to download NIP binary"
        print_info "Please check your internet connection and try again"
        exit 1
    fi

    # Make binary executable
    chmod +x "$temp_binary"

    # Verify binary
    if ! verify_binary "$temp_binary"; then
        print_error "Binary verification failed"
        exit 1
    fi

    print_status "Binary downloaded and verified"

    # Install binary
    print_info "Installing NIP to $INSTALL_DIR/$BINARY_NAME..."
    cp "$temp_binary" "$INSTALL_DIR/$BINARY_NAME"
    chmod +x "$INSTALL_DIR/$BINARY_NAME"
    print_status "NIP binary installed"

    # Create system directories
    create_directories

    # Setup system integration
    setup_system_integration

    # Installation complete
    echo ""
    echo -e "${GREEN}${CHECK} NIP installation complete!${NC}"
    echo ""

    # Show version
    local version_output
    if version_output=$("$INSTALL_DIR/$BINARY_NAME" --version 2>/dev/null); then
        print_status "Installed: $version_output"
    else
        print_info "NIP installed successfully (version check requires setup)"
    fi

    echo ""
    echo -e "${PURPLE}${SANTA} Welcome to NIP v0.2.0 'Weihnachtsmann'!${NC}"
    echo ""
    echo -e "${CYAN}${ROCKET} Next steps:${NC}"
    echo -e "${CYAN}  1. Initialize NIP:     ${YELLOW}nip setup${NC}"
    echo -e "${CYAN}  2. Check status:       ${YELLOW}nip status${NC}"
    echo -e "${CYAN}  3. Install packages:   ${YELLOW}nip graft aur firefox${NC}"
    echo -e "${CYAN}  4. Build from source:  ${YELLOW}nip build nginx +http3${NC}"
    echo ""
    echo -e "${CYAN}${PACKAGE} Documentation: ${BLUE}https://git.maiwald.work/Nexus/NexusToolKit${NC}"
    echo -e "${CYAN}${WRENCH} Support:       ${BLUE}https://git.maiwald.work/Nexus/NexusToolKit/issues${NC}"
    echo ""
    echo -e "${PURPLE}${SANTA} Happy packaging! ✨${NC}"
}

# Handle command line arguments
case "${1:-}" in
    --help|-h)
        echo "NIP Bootstrap Installer"
        echo ""
        echo "Usage:"
        echo "  curl -L https://git.maiwald.work/Nexus/NexusToolKit/raw/branch/main/nip/install.sh | bash"
        echo "  wget -O- https://git.maiwald.work/Nexus/NexusToolKit/raw/branch/main/nip/install.sh | bash"
        echo ""
        echo "Options:"
        echo "  --help, -h     Show this help message"
        echo "  --version, -v  Show version information"
        echo ""
        echo "Environment variables:"
        echo "  INSTALL_DIR    Installation directory (default: /usr/local/bin)"
        echo ""
        exit 0
        ;;
    --version|-v)
        echo "NIP Bootstrap Installer ${VERSION}"
        echo "Repository: https://git.maiwald.work/Nexus/NexusToolKit"
        exit 0
        ;;
    *)
        # Run main installation
        main "$@"
        ;;
esac