#!/bin/bash
# ============================================================================
# Ethereon DDoS Defense Agent - Installer
# ============================================================================
#
# Usage:
#   Method 1 — Download and pipe to bash:
#     curl -sSL http://SERVER:5000/api/agent/download | bash -s -- --server http://SERVER:5000
#
#   Method 2 — Run directly:
#     chmod +x install.sh
#     ./install.sh --server http://SERVER:5000
#
#   Optional flags:
#     --server URL        Dashboard server URL (required)
#     --agent-id ID       Custom agent identifier (auto-generated if omitted)
#     --uninstall         Remove the agent and service
#     --no-start          Install but do not start the service
#     --skip-deps         Skip dependency installation (assume already installed)
#     --help              Show this help message
#
# ============================================================================

set -euo pipefail

# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------
INSTALL_DIR="/opt/ethereon-agent"
AGENT_SCRIPT="ethereon_agent.py"
SERVICE_NAME="ethereon-agent"
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
AGENT_URL=""        # Populated from --server
AGENT_ID=""         # Populated from --agent-id (optional)
NO_START=0
SKIP_DEPS=0
UNINSTALL=0

# Colors (disabled when not a tty)
if [ -t 1 ]; then
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    CYAN='\033[0;36m'
    BOLD='\033[1m'
    NC='\033[0m'
else
    RED='' GREEN='' YELLOW='' CYAN='' BOLD='' NC=''
fi

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
log_info()    { echo -e "${GREEN}[INFO]${NC}  $*"; }
log_warn()    { echo -e "${YELLOW}[WARN]${NC}  $*"; }
log_error()   { echo -e "${RED}[ERROR]${NC} $*" >&2; }
log_step()    { echo -e "${CYAN}[STEP]${NC}  $*"; }

check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        log_error "This script must be run as root (use sudo)."
        exit 1
    fi
}

usage() {
    head -25 "$0" | tail -20 | sed 's/^# \?//'
    exit 0
}

# ---------------------------------------------------------------------------
# Parse arguments
# ---------------------------------------------------------------------------
parse_args() {
    while [ $# -gt 0 ]; do
        case "$1" in
            --server)
                AGENT_URL="$2"
                shift 2
                ;;
            --agent-id)
                AGENT_ID="$2"
                shift 2
                ;;
            --no-start)
                NO_START=1
                shift
                ;;
            --skip-deps)
                SKIP_DEPS=1
                shift
                ;;
            --uninstall)
                UNINSTALL=1
                shift
                ;;
            --help|-h)
                usage
                ;;
            *)
                log_error "Unknown argument: $1"
                echo ""
                usage
                exit 1
                ;;
        esac
    done
}

# ---------------------------------------------------------------------------
# Uninstall
# ---------------------------------------------------------------------------
do_uninstall() {
    log_step "Uninstalling Ethereon DDoS Defense Agent..."

    if systemctl is-active --quiet "${SERVICE_NAME}" 2>/dev/null; then
        log_info "Stopping service..."
        systemctl stop "${SERVICE_NAME}" || true
    fi

    if systemctl is-enabled --quiet "${SERVICE_NAME}" 2>/dev/null; then
        log_info "Disabling service..."
        systemctl disable "${SERVICE_NAME}" || true
    fi

    if [ -f "${SERVICE_FILE}" ]; then
        rm -f "${SERVICE_FILE}"
        systemctl daemon-reload
        log_info "Removed service file: ${SERVICE_FILE}"
    fi

    if [ -d "${INSTALL_DIR}" ]; then
        rm -rf "${INSTALL_DIR}"
        log_info "Removed install directory: ${INSTALL_DIR}"
    fi

    # Flush iptables chain if it exists
    if command -v iptables &>/dev/null; then
        iptables -F ETHEREON_DEFENSE 2>/dev/null || true
        iptables -D INPUT -j ETHEREON_DEFENSE 2>/dev/null || true
        iptables -X ETHEREON_DEFENSE 2>/dev/null || true
        log_info "Cleaned up iptables rules."
    fi

    echo ""
    log_info "Ethereon Agent has been fully uninstalled."
    exit 0
}

# ---------------------------------------------------------------------------
# Dependency checks & installation
# ---------------------------------------------------------------------------
check_python() {
    if command -v python3 &>/dev/null; then
        PYTHON_BIN=$(command -v python3)
        PY_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
        log_info "Found Python ${PY_VERSION} at ${PYTHON_BIN}"
        # Verify minimum version 3.7
        python3 -c "
import sys
if sys.version_info < (3, 7):
    print('ERROR: Python 3.7+ is required.')
    sys.exit(1)
"
        return 0
    else
        log_error "Python 3 is not installed."
        log_info "Install it with: sudo apt install -y python3 python3-pip"
        exit 1
    fi
}

install_deps() {
    if [ "${SKIP_DEPS}" -eq 1 ]; then
        log_info "Skipping dependency installation (--skip-deps)."
        return 0
    fi

    log_step "Installing required Python packages..."

    # Ensure pip is available
    if ! python3 -m pip --version &>/dev/null; then
        log_info "Installing pip..."
        if command -v apt-get &>/dev/null; then
            apt-get update -qq && apt-get install -y -qq python3-pip
        elif command -v yum &>/dev/null; then
            yum install -y python3-pip
        elif command -v dnf &>/dev/null; then
            dnf install -y python3-pip
        else
            log_error "Cannot install pip automatically. Please install python3-pip manually."
            exit 1
        fi
    fi

    python3 -m pip install --quiet --upgrade pip
    python3 -m pip install --quiet requests psutil

    log_info "Dependencies installed."
}

check_iptables() {
    if command -v iptables &>/dev/null; then
        log_info "iptables found: $(command -v iptables)"
    else
        log_warn "iptables not found. IP blocking will not work on this host."
        log_warn "Install iptables for full functionality."
    fi
}

# ---------------------------------------------------------------------------
# Download / install agent
# ---------------------------------------------------------------------------
install_agent() {
    log_step "Setting up agent in ${INSTALL_DIR}..."

    # Create install directory
    mkdir -p "${INSTALL_DIR}"

    # Determine download URL for the Python agent script
    local download_url="${AGENT_URL%/}/api/agent/download/python"

    # Attempt to download from the dashboard
    log_info "Downloading agent script from ${download_url}..."
    local http_code
    http_code=$(curl -sSL -o "${INSTALL_DIR}/${AGENT_SCRIPT}" -w "%{http_code}" "${download_url}" 2>/dev/null || true)

    if [ "${http_code}" = "200" ] && [ -s "${INSTALL_DIR}/${AGENT_SCRIPT}" ]; then
        log_info "Agent script downloaded successfully."
    else
        log_warn "Could not download from dashboard (HTTP ${http_code:-N/A})."
        log_info "Using local bundled agent script..."

        # Check if the script is bundled alongside the installer
        local script_dir
        script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
        if [ -f "${script_dir}/${AGENT_SCRIPT}" ]; then
            cp "${script_dir}/${AGENT_SCRIPT}" "${INSTALL_DIR}/${AGENT_SCRIPT}"
            log_info "Copied local agent script."
        else
            log_error "Agent script not found locally either."
            log_error "Place ethereon_agent.py next to this installer, or ensure the dashboard download endpoint works."
            exit 1
        fi
    fi

    chmod 755 "${INSTALL_DIR}/${AGENT_SCRIPT}"
    log_info "Agent script installed to ${INSTALL_DIR}/${AGENT_SCRIPT}"
}

# ---------------------------------------------------------------------------
# Systemd service
# ---------------------------------------------------------------------------
create_service() {
    log_step "Creating systemd service..."

    # Build the ExecStart command using the detected Python path
    local exec_start="${PYTHON_BIN} ${INSTALL_DIR}/${AGENT_SCRIPT} --server ${AGENT_URL}"
    if [ -n "${AGENT_ID}" ]; then
        exec_start="${exec_start} --agent-id ${AGENT_ID}"
    fi

    cat > "${SERVICE_FILE}" <<EOF
[Unit]
Description=Ethereon DDoS Defense Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=${exec_start}
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=${SERVICE_NAME}

# Hardening
NoNewPrivileges=no
ProtectSystem=false
ProtectHome=false

# Environment
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    log_info "Service file created at ${SERVICE_FILE}"
}

start_service() {
    if [ "${NO_START}" -eq 1 ]; then
        log_info "Service not started (--no-start flag)."
        log_info "Start manually with: sudo systemctl start ${SERVICE_NAME}"
        return 0
    fi

    log_step "Starting service..."
    systemctl enable "${SERVICE_NAME}"
    systemctl start "${SERVICE_NAME}"
    sleep 2

    if systemctl is-active --quiet "${SERVICE_NAME}"; then
        log_info "Service is ${BOLD}running${NC}."
    else
        log_error "Service failed to start. Check logs:"
        log_error "  journalctl -u ${SERVICE_NAME} -n 50 --no-pager"
        exit 1
    fi
}

print_banner() {
    echo ""
    echo -e "${CYAN}============================================================${NC}"
    echo -e "${CYAN}  Ethereon DDoS Defense Agent - Installation Complete${NC}"
    echo -e "${CYAN}============================================================${NC}"
    echo ""
    echo -e "  ${BOLD}Agent Directory${NC}  : ${INSTALL_DIR}"
    echo -e "  ${BOLD}Agent Script${NC}     : ${INSTALL_DIR}/${AGENT_SCRIPT}"
    echo -e "  ${BOLD}Dashboard URL${NC}    : ${AGENT_URL}"
    if [ -n "${AGENT_ID}" ]; then
        echo -e "  ${BOLD}Agent ID${NC}         : ${AGENT_ID}"
    else
        echo -e "  ${BOLD}Agent ID${NC}         : (auto-generated on first run)"
    fi
    echo -e "  ${BOLD}Service Name${NC}     : ${SERVICE_NAME}"
    echo -e "  ${BOLD}Service File${NC}     : ${SERVICE_FILE}"
    echo ""
    echo -e "  ${BOLD}Useful Commands:${NC}"
    echo "    sudo systemctl status ${SERVICE_NAME}"
    echo "    sudo systemctl restart ${SERVICE_NAME}"
    echo "    sudo systemctl stop ${SERVICE_NAME}"
    echo "    journalctl -u ${SERVICE_NAME} -f"
    echo ""
    echo -e "  ${BOLD}Uninstall:${NC}"
    echo "    curl -sSL ${AGENT_URL}/api/agent/download | bash -s -- --server ${AGENT_URL} --uninstall"
    echo ""
    echo -e "${CYAN}============================================================${NC}"
    echo ""
}

# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
    parse_args "$@"

    echo ""
    echo -e "${CYAN}Ethereon DDoS Defense Agent - Installer${NC}"
    echo ""

    # Handle uninstall
    if [ "${UNINSTALL}" -eq 1 ]; then
        check_root
        do_uninstall
    fi

    # Validate required arguments
    if [ -z "${AGENT_URL}" ]; then
        log_error "--server URL is required."
        echo ""
        echo "Usage:"
        echo "  $0 --server http://YOUR_SERVER:5000"
        echo "  curl -sSL http://SERVER:5000/api/agent/download | bash -s -- --server http://SERVER:5000"
        exit 1
    fi

    # Validate URL format
    if [[ ! "${AGENT_URL}" =~ ^https?:// ]]; then
        log_error "Server URL must start with http:// or https://"
        exit 1
    fi

    check_root
    check_python
    check_iptables
    install_deps
    install_agent
    create_service
    start_service
    print_banner
}

main "$@"
