#!/usr/bin/env bash
#
# MYCURE Syncbased Management Script
# 
# This script provides a unified interface for installing, uninstalling, 
# and managing the MYCURE Syncbased binary on your system.
#
# Usage:
#   # Install latest version
#   curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash
#   
#   # Install specific version
#   curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- install --version 5.137.72
#   
#   # Install for user only
#   curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- install --user
#   
#   # Install with systemd service
#   curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- install --service
#   
#   # Uninstall
#   curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- uninstall
#   
#   # Uninstall with config removal
#   curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- uninstall --purge
#   
#   # Install systemd service only
#   curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- service --install
#   
#   # Remove systemd service
#   curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- service --remove
#

set -euo pipefail

# Configuration
BINARY_NAME="syncbased"
DOWNLOAD_BASE_URL="https://downloads.mycure.md/syncbase"
GITHUB_REPO="mycure/syncbased"
DEFAULT_INSTALL_DIR="/opt/mycure"
USER_INSTALL_DIR="${HOME}/.local/bin"
CONFIG_DIR="${HOME}/.mycure"
SERVICE_NAME="mycure-syncbased"

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

# Global variables
COMMAND=""
VERSION="latest"
INSTALL_USER=false
INSTALL_SERVICE=false
PURGE_CONFIG=false
FORCE_INSTALL=false

# Utility functions
log() {
    echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $*"
}

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

success() {
    echo -e "${GREEN}[SUCCESS]${NC} $*"
}

warning() {
    echo -e "${YELLOW}[WARNING]${NC} $*"
}

# Check if running with sudo when needed
check_sudo() {
    if [[ $EUID -ne 0 ]] && [[ "$INSTALL_USER" == false ]]; then
        error "This operation requires sudo privileges for system-wide installation"
        echo "Run with: curl -fsSL <url> | sudo bash -s -- $*"
        echo "Or use --user flag for user installation"
        exit 1
    fi
}

# Detect OS and architecture
detect_platform() {
    local os arch

    # Detect OS
    case "$(uname -s)" in
        Linux*)     os="linux" ;;
        Darwin*)    os="darwin" ;;
        *)          
            error "Unsupported operating system: $(uname -s)"
            exit 1
            ;;
    esac

    # Detect architecture
    case "$(uname -m)" in
        x86_64|amd64)   arch="amd64" ;;
        aarch64|arm64)  arch="arm64" ;;
        *)              
            error "Unsupported architecture: $(uname -m)"
            exit 1
            ;;
    esac

    echo "${os}_${arch}"
}

# Get latest version from downloads server
get_latest_version() {
    log "Fetching latest version..."
    
    # Try to get version from downloads page
    local version_url="${DOWNLOAD_BASE_URL}/latest.txt"
    local version
    
    if command -v curl &> /dev/null; then
        version=$(curl -fsSL "$version_url" 2>/dev/null || echo "")
    elif command -v wget &> /dev/null; then
        version=$(wget -qO- "$version_url" 2>/dev/null || echo "")
    fi
    
    if [[ -z "$version" ]]; then
        error "Failed to fetch latest version"
        echo "Please specify a version with --version flag"
        exit 1
    fi
    
    echo "$version"
}

# Download binary
download_binary() {
    local platform=$1
    local version=$2
    local temp_dir=$3
    
    local filename="${BINARY_NAME}_${platform}_${version}.tgz"
    local download_url="${DOWNLOAD_BASE_URL}/${filename}"
    local checksum_url="${DOWNLOAD_BASE_URL}/${filename}.sha256"
    
    log "Downloading ${BINARY_NAME} v${version} for ${platform}..."
    
    # Download binary
    if command -v curl &> /dev/null; then
        curl -fsSL --progress-bar "$download_url" -o "${temp_dir}/${filename}"
    elif command -v wget &> /dev/null; then
        wget --show-progress -qO "${temp_dir}/${filename}" "$download_url"
    else
        error "Neither curl nor wget found. Please install one of them."
        exit 1
    fi
    
    # Download and verify checksum
    log "Verifying checksum..."
    if command -v curl &> /dev/null; then
        curl -fsSL "$checksum_url" -o "${temp_dir}/${filename}.sha256"
    else
        wget -qO "${temp_dir}/${filename}.sha256" "$checksum_url"
    fi
    
    # Verify checksum
    cd "$temp_dir"
    if command -v sha256sum &> /dev/null; then
        sha256sum -c "${filename}.sha256" &> /dev/null || {
            error "Checksum verification failed"
            exit 1
        }
    elif command -v shasum &> /dev/null; then
        shasum -a 256 -c "${filename}.sha256" &> /dev/null || {
            error "Checksum verification failed"
            exit 1
        }
    else
        warning "Cannot verify checksum: sha256sum/shasum not found"
    fi
    cd - > /dev/null
    
    success "Download complete and verified"
    echo "${temp_dir}/${filename}"
}

# Extract binary
extract_binary() {
    local archive_path=$1
    local extract_dir=$2
    
    log "Extracting binary..."
    tar -xzf "$archive_path" -C "$extract_dir"
    
    # Find the binary
    local binary_path="${extract_dir}/${BINARY_NAME}"
    if [[ ! -f "$binary_path" ]]; then
        error "Binary not found in archive"
        exit 1
    fi
    
    chmod +x "$binary_path"
    echo "$binary_path"
}

# Install binary
install_binary() {
    local binary_path=$1
    local install_dir=$2
    
    log "Installing ${BINARY_NAME} to ${install_dir}..."
    
    # Create installation directory
    mkdir -p "$install_dir"
    
    # Backup existing binary if present
    if [[ -f "${install_dir}/${BINARY_NAME}" ]]; then
        log "Backing up existing installation..."
        mv "${install_dir}/${BINARY_NAME}" "${install_dir}/${BINARY_NAME}.backup.$(date +%Y%m%d%H%M%S)"
    fi
    
    # Copy binary
    cp "$binary_path" "${install_dir}/${BINARY_NAME}"
    chmod +x "${install_dir}/${BINARY_NAME}"
    
    success "Binary installed successfully"
}

# Setup PATH
setup_path() {
    local install_dir=$1
    local shell_rc=""
    
    # Skip if already in PATH
    if command -v "$BINARY_NAME" &> /dev/null; then
        log "syncbased is already in PATH"
        return
    fi
    
    # Determine shell configuration file
    if [[ -n "${BASH_VERSION:-}" ]]; then
        shell_rc="${HOME}/.bashrc"
    elif [[ -n "${ZSH_VERSION:-}" ]]; then
        shell_rc="${HOME}/.zshrc"
    else
        shell_rc="${HOME}/.profile"
    fi
    
    # Add to PATH if not already present
    if [[ -f "$shell_rc" ]] && ! grep -q "$install_dir" "$shell_rc"; then
        echo "" >> "$shell_rc"
        echo "# Added by MYCURE Syncbased installer" >> "$shell_rc"
        echo "export PATH=\"${install_dir}:\$PATH\"" >> "$shell_rc"
        log "Added ${install_dir} to PATH in ${shell_rc}"
        warning "Please run 'source ${shell_rc}' or restart your terminal"
    fi
}

# Create configuration directory
create_config_dir() {
    if [[ ! -d "$CONFIG_DIR" ]]; then
        log "Creating configuration directory at ${CONFIG_DIR}..."
        mkdir -p "$CONFIG_DIR"
        
        # Set proper ownership if running with sudo
        if [[ $EUID -eq 0 ]] && [[ -n "${SUDO_USER:-}" ]]; then
            chown -R "${SUDO_USER}:$(id -gn "${SUDO_USER}")" "$CONFIG_DIR"
        fi
    fi
}

# Find binary location
find_binary() {
    local locations=(
        "${DEFAULT_INSTALL_DIR}/${BINARY_NAME}"
        "${USER_INSTALL_DIR}/${BINARY_NAME}"
        "/usr/local/bin/${BINARY_NAME}"
        "/usr/bin/${BINARY_NAME}"
    )
    
    for loc in "${locations[@]}"; do
        if [[ -f "$loc" ]]; then
            echo "$loc"
            return 0
        fi
    done
    
    # Check PATH
    if command -v "$BINARY_NAME" &> /dev/null; then
        command -v "$BINARY_NAME"
        return 0
    fi
    
    return 1
}

# Create systemd service
create_systemd_service() {
    local binary_path=$1
    
    if [[ "$(uname -s)" != "Linux" ]]; then
        error "Systemd services are only supported on Linux"
        return 1
    fi
    
    log "Creating systemd service..."
    
    # Check if we need sudo for writing service file
    if [[ $EUID -ne 0 ]]; then
        error "Need sudo privileges to create systemd service"
        echo "Please run: sudo $0 service --install"
        exit 1
    fi
    
    local service_file="/etc/systemd/system/${SERVICE_NAME}.service"
    
    cat > "$service_file" << EOF
[Unit]
Description=MYCURE Syncbased Service
Documentation=https://github.com/mycure/syncbased
After=network.target

[Service]
Type=simple
ExecStart=${binary_path} start
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=${SERVICE_NAME}
User=${SUDO_USER:-$USER}
Environment="HOME=${HOME}"
Environment="USER=${SUDO_USER:-$USER}"
WorkingDirectory=${CONFIG_DIR}

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    success "Systemd service created: ${SERVICE_NAME}"
    echo ""
    echo "To enable and start the service, run:"
    echo "  sudo systemctl enable ${SERVICE_NAME}"
    echo "  sudo systemctl start ${SERVICE_NAME}"
}

# Remove systemd service
remove_systemd_service() {
    if [[ "$(uname -s)" != "Linux" ]]; then
        return
    fi
    
    local service_file="/etc/systemd/system/${SERVICE_NAME}.service"
    
    if [[ -f "$service_file" ]]; then
        log "Stopping and removing systemd service..."
        
        # Check if we need sudo
        if [[ $EUID -ne 0 ]]; then
            error "Need sudo privileges to remove systemd service"
            echo "Please run: sudo $0 service --remove"
            exit 1
        fi
        
        # Stop and disable service
        systemctl stop "${SERVICE_NAME}" 2>/dev/null || true
        systemctl disable "${SERVICE_NAME}" 2>/dev/null || true
        
        # Remove service file
        rm -f "$service_file"
        systemctl daemon-reload
        
        success "Systemd service removed"
    fi
}

# Remove binary
remove_binary() {
    local binary_path=$1
    
    log "Removing binary at ${binary_path}..."
    
    # Check if we need sudo
    if [[ -w "$binary_path" ]]; then
        rm -f "$binary_path"
    else
        if [[ $EUID -ne 0 ]]; then
            error "Need sudo privileges to remove ${binary_path}"
            echo "Please run: sudo $0 uninstall"
            exit 1
        fi
        rm -f "$binary_path"
    fi
    
    # Remove directory if empty
    local install_dir
    install_dir=$(dirname "$binary_path")
    if [[ -d "$install_dir" ]] && [[ -z "$(ls -A "$install_dir")" ]]; then
        rmdir "$install_dir" 2>/dev/null || true
    fi
    
    success "Binary removed"
}

# Remove from PATH
remove_from_path() {
    local install_dirs=("$DEFAULT_INSTALL_DIR" "$USER_INSTALL_DIR")
    local shell_configs=("${HOME}/.bashrc" "${HOME}/.zshrc" "${HOME}/.profile")
    
    for config in "${shell_configs[@]}"; do
        if [[ -f "$config" ]]; then
            # Create backup
            cp "$config" "${config}.backup.$(date +%Y%m%d%H%M%S)"
            
            # Remove PATH entries
            for dir in "${install_dirs[@]}"; do
                sed -i.tmp "/${dir//\//\\/}/d" "$config"
            done
            
            # Remove installer comments
            sed -i.tmp '/# Added by MYCURE Syncbased installer/d' "$config"
            
            # Clean up temp files
            rm -f "${config}.tmp"
            
            log "Cleaned PATH entries from ${config}"
        fi
    done
}

# Remove configuration
remove_config() {
    if [[ "$PURGE_CONFIG" != true ]]; then
        return
    fi
    
    if [[ -d "$CONFIG_DIR" ]]; then
        log "Removing configuration directory..."
        
        # Backup before removal
        local backup_dir="${CONFIG_DIR}.backup.$(date +%Y%m%d%H%M%S)"
        mv "$CONFIG_DIR" "$backup_dir"
        
        log "Configuration backed up to ${backup_dir}"
        warning "Configuration directory moved to backup. Manually delete if no longer needed."
    fi
}

# Command: install
cmd_install() {
    log "Starting MYCURE Syncbased installation..."
    
    # Determine installation directory
    local install_dir
    if [[ "$INSTALL_USER" == true ]]; then
        install_dir="$USER_INSTALL_DIR"
    else
        install_dir="$DEFAULT_INSTALL_DIR"
        check_sudo
    fi
    
    # Get version if not specified
    if [[ "$VERSION" == "latest" ]]; then
        VERSION=$(get_latest_version)
    fi
    
    # Detect platform
    local platform
    platform=$(detect_platform)
    
    log "Installing syncbased v${VERSION} for ${platform}"
    
    # Create temporary directory
    local temp_dir
    temp_dir=$(mktemp -d)
    trap 'rm -rf "$temp_dir"' EXIT
    
    # Download binary
    local archive_path
    archive_path=$(download_binary "$platform" "$VERSION" "$temp_dir")
    
    # Extract binary
    local binary_path
    binary_path=$(extract_binary "$archive_path" "$temp_dir")
    
    # Install binary
    install_binary "$binary_path" "$install_dir"
    
    # Setup PATH for user installations
    if [[ "$INSTALL_USER" == true ]]; then
        setup_path "$install_dir"
    fi
    
    # Create configuration directory
    create_config_dir
    
    # Create systemd service if requested
    if [[ "$INSTALL_SERVICE" == true ]]; then
        create_systemd_service "${install_dir}/${BINARY_NAME}"
    fi
    
    # Print success message
    echo ""
    success "MYCURE Syncbased v${VERSION} has been installed successfully!"
    echo ""
    echo "Installation details:"
    echo "  Binary location: ${install_dir}/${BINARY_NAME}"
    echo "  Config directory: ${CONFIG_DIR}"
    echo ""
    echo "Next steps:"
    echo "  1. Initialize syncbased with your sync key:"
    echo "     ${BINARY_NAME} init <your-sync-key>"
    echo ""
    echo "  2. Start syncbased:"
    echo "     ${BINARY_NAME} start"
    echo ""
    
    if [[ "$INSTALL_SERVICE" == true ]] && [[ "$(uname -s)" == "Linux" ]]; then
        echo "  Or enable the systemd service:"
        echo "     sudo systemctl enable ${SERVICE_NAME}"
        echo "     sudo systemctl start ${SERVICE_NAME}"
        echo ""
    fi
}

# Command: uninstall
cmd_uninstall() {
    log "Starting MYCURE Syncbased uninstallation..."
    
    # Find binary location
    local binary_path
    if binary_path=$(find_binary); then
        log "Found syncbased at: ${binary_path}"
    else
        error "syncbased binary not found on this system"
        exit 1
    fi
    
    # Confirm uninstallation
    echo ""
    warning "This will remove syncbased from your system."
    if [[ "$PURGE_CONFIG" == true ]]; then
        warning "Configuration directory will also be removed (backed up first)."
    fi
    echo ""
    read -p "Continue with uninstallation? [y/N] " -n 1 -r
    echo ""
    
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        log "Uninstallation cancelled"
        exit 0
    fi
    
    # Stop and remove systemd service
    remove_systemd_service
    
    # Remove binary
    remove_binary "$binary_path"
    
    # Remove from PATH
    remove_from_path
    
    # Remove configuration if requested
    remove_config
    
    # Success message
    echo ""
    success "MYCURE Syncbased has been uninstalled successfully!"
    
    if [[ "$PURGE_CONFIG" != true ]] && [[ -d "$CONFIG_DIR" ]]; then
        echo ""
        echo "Configuration directory still exists at: ${CONFIG_DIR}"
        echo "To remove it, run: $0 uninstall --purge"
    fi
}

# Command: service
cmd_service() {
    local action=""
    
    # Parse service subcommand
    while [[ $# -gt 0 ]]; do
        case $1 in
            --install)
                action="install"
                shift
                ;;
            --remove)
                action="remove"
                shift
                ;;
            *)
                error "Unknown service option: $1"
                exit 1
                ;;
        esac
    done
    
    if [[ -z "$action" ]]; then
        error "Service action required: --install or --remove"
        exit 1
    fi
    
    if [[ "$action" == "install" ]]; then
        # Find binary location
        local binary_path
        if binary_path=$(find_binary); then
            create_systemd_service "$binary_path"
        else
            error "syncbased binary not found. Please install it first."
            exit 1
        fi
    elif [[ "$action" == "remove" ]]; then
        remove_systemd_service
    fi
}

# Parse command line arguments
parse_args() {
    # If no arguments provided, default to install
    if [[ $# -eq 0 ]]; then
        COMMAND="install"
        return
    fi
    
    # Parse command
    case $1 in
        install|uninstall|service)
            COMMAND="$1"
            shift
            ;;
        --help|-h)
            show_help
            exit 0
            ;;
        *)
            # If first argument is not a command, treat as install with flags
            COMMAND="install"
            ;;
    esac
    
    # Parse flags
    while [[ $# -gt 0 ]]; do
        case $1 in
            --version)
                VERSION="$2"
                shift 2
                ;;
            --user)
                INSTALL_USER=true
                shift
                ;;
            --service)
                INSTALL_SERVICE=true
                shift
                ;;
            --purge)
                PURGE_CONFIG=true
                shift
                ;;
            --force)
                FORCE_INSTALL=true
                shift
                ;;
            --install|--remove)
                # These are handled by cmd_service
                break
                ;;
            --help|-h)
                show_help
                exit 0
                ;;
            *)
                error "Unknown option: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# Show help
show_help() {
    cat << EOF
MYCURE Syncbased Management Script

Usage:
    $0 [command] [options]

Commands:
    install     Install syncbased (default)
    uninstall   Remove syncbased
    service     Manage systemd service

Install Options:
    --version <version>  Install specific version (default: latest)
    --user              Install to user directory (~/.local/bin)
    --service           Create systemd service (Linux only)
    --force             Force reinstallation

Uninstall Options:
    --purge             Also remove configuration directory

Service Options:
    --install           Install systemd service
    --remove            Remove systemd service

Examples:
    # Install latest version system-wide
    curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | sudo bash

    # Install specific version for current user
    curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- install --version 5.137.72 --user

    # Install with systemd service
    curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | sudo bash -s -- install --service

    # Uninstall completely
    curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | bash -s -- uninstall --purge

    # Install systemd service only
    curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | sudo bash -s -- service --install

    # Remove systemd service
    curl -fsSL https://downloads.mycure.md/syncbase/syncbased.sh | sudo bash -s -- service --remove
EOF
}

# Main function
main() {
    # Parse arguments
    parse_args "$@"
    
    # Execute command
    case "$COMMAND" in
        install)
            cmd_install
            ;;
        uninstall)
            cmd_uninstall
            ;;
        service)
            cmd_service "$@"
            ;;
        *)
            error "Unknown command: $COMMAND"
            show_help
            exit 1
            ;;
    esac
}

# Run main function
main "$@"