#!/bin/bash
# ═══════════════════════════════════════════════════════════════
# HYDRA Security — Universal Installer
# "Cut off a head, two grow back."
#
# Usage:
#   curl -fsSL https://hydrasecurity.dev/install.sh | bash
#   curl -fsSL https://hydrasecurity.dev/install.sh | bash -s -- --license YOUR-KEY
#
# Supports: Ubuntu 20+, Debian 11+, AlmaLinux 8+, Rocky 8+, CentOS 8+
# Detects:  cPanel, CyberPanel, Plesk, DirectAdmin, bare metal
# ═══════════════════════════════════════════════════════════════

set -e

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

VERSION="2.3"
HYDRA_DIR="/opt/hydra"
HYDRA_BIN="/usr/local/bin/hydra"
HYDRA_USER="root"
DOWNLOAD_URL="https://hydrasecurity.dev/releases"
LICENSE_KEY=""
WATCH_DIRS=""

# Parse args
while [[ $# -gt 0 ]]; do
    case $1 in
        --license) LICENSE_KEY="$2"; shift 2 ;;
        --watch) WATCH_DIRS="$2"; shift 2 ;;
        --uninstall) UNINSTALL=1; shift ;;
        *) shift ;;
    esac
done

banner() {
    echo -e "${GREEN}"
    echo '  ██╗  ██╗██╗   ██╗██████╗ ██████╗  █████╗ '
    echo '  ██║  ██║╚██╗ ██╔╝██╔══██╗██╔══██╗██╔══██╗'
    echo '  ███████║ ╚████╔╝ ██║  ██║██████╔╝███████║'
    echo '  ██╔══██║  ╚██╔╝  ██║  ██║██╔══██╗██╔══██║'
    echo '  ██║  ██║   ██║   ██████╔╝██║  ██║██║  ██║'
    echo '  ╚═╝  ╚═╝   ╚═╝   ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝'
    echo -e "${NC}"
    echo -e "  ${CYAN}Self-Healing Server Protection v${VERSION}${NC}"
    echo -e "  ${CYAN}\"Cut off a head, two grow back.\"${NC}"
    echo ""
}

log() { echo -e "  ${GREEN}[+]${NC} $1"; }
warn() { echo -e "  ${YELLOW}[!]${NC} $1"; }
err() { echo -e "  ${RED}[x]${NC} $1"; exit 1; }
step() { echo -e "\n  ${BOLD}${CYAN}=== $1 ===${NC}"; }

# ═══════════════════════════════════════
# UNINSTALL
# ═══════════════════════════════════════
if [ "$UNINSTALL" = "1" ]; then
    banner
    step "Uninstalling HYDRA"
    systemctl stop hydra 2>/dev/null || true
    systemctl disable hydra 2>/dev/null || true
    rm -f /etc/systemd/system/hydra.service
    rm -f "$HYDRA_BIN"
    rm -rf "$HYDRA_DIR"
    rm -rf /etc/hydra
    systemctl daemon-reload
    log "HYDRA uninstalled."
    exit 0
fi

# ═══════════════════════════════════════
# PRE-FLIGHT CHECKS
# ═══════════════════════════════════════
banner
step "Pre-flight checks"

# Must be root
if [ "$(id -u)" -ne 0 ]; then
    err "Must run as root. Use: sudo bash install.sh"
fi

# Detect OS
if [ -f /etc/os-release ]; then
    . /etc/os-release
    OS_NAME="$ID"
    OS_VERSION="$VERSION_ID"
    OS_PRETTY="$PRETTY_NAME"
else
    err "Cannot detect OS. /etc/os-release not found."
fi

log "OS: $OS_PRETTY"

# Detect architecture
ARCH=$(uname -m)
case $ARCH in
    x86_64) GO_ARCH="amd64" ;;
    aarch64) GO_ARCH="arm64" ;;
    *) err "Unsupported architecture: $ARCH" ;;
esac
log "Architecture: $ARCH ($GO_ARCH)"

# Detect panel
PANEL="none"
if [ -d /usr/local/cpanel ]; then PANEL="cPanel"
elif [ -f /usr/local/CyberPanel/CyberCP/manage.py ]; then PANEL="CyberPanel"
elif [ -d /usr/local/psa ]; then PANEL="Plesk"
elif [ -d /usr/local/directadmin ]; then PANEL="DirectAdmin"
elif [ -d /usr/share/webmin ]; then PANEL="Webmin"
fi
log "Panel: $PANEL"

# Detect web server
WEBSERVER="none"
if command -v nginx &>/dev/null; then WEBSERVER="nginx"
elif command -v httpd &>/dev/null; then WEBSERVER="Apache"
elif [ -d /usr/local/lsws ]; then WEBSERVER="LiteSpeed"
elif command -v caddy &>/dev/null; then WEBSERVER="Caddy"
fi
log "Web server: $WEBSERVER"

# Detect mail
MAILSERVER="none"
if command -v postfix &>/dev/null || [ -f /usr/sbin/postfix ]; then MAILSERVER="Postfix"
elif command -v exim4 &>/dev/null || [ -f /usr/sbin/exim4 ]; then MAILSERVER="Exim"
fi
if [ "$MAILSERVER" != "none" ]; then
    log "Mail server: $MAILSERVER"
fi

# ═══════════════════════════════════════
# AUTO-DETECT WATCH DIRECTORIES
# ═══════════════════════════════════════
step "Detecting directories to protect"

if [ -z "$WATCH_DIRS" ]; then
    DIRS_TO_WATCH=""

    # Web roots by panel
    case $PANEL in
        cPanel)
            [ -d /home ] && DIRS_TO_WATCH="/home"
            [ -d /etc/apache2 ] && DIRS_TO_WATCH="$DIRS_TO_WATCH,/etc/apache2"
            ;;
        CyberPanel)
            [ -d /home ] && DIRS_TO_WATCH="/home"
            ;;
        Plesk)
            [ -d /var/www/vhosts ] && DIRS_TO_WATCH="/var/www/vhosts"
            ;;
        *)
            # Bare metal / manual
            for dir in /var/www /var/www/html /var/www/hydrasecurity.dev /srv/www; do
                [ -d "$dir" ] && DIRS_TO_WATCH="${DIRS_TO_WATCH:+$DIRS_TO_WATCH,}$dir"
            done
            ;;
    esac

    # Always watch web server configs
    [ -d /etc/nginx ] && DIRS_TO_WATCH="${DIRS_TO_WATCH:+$DIRS_TO_WATCH,}/etc/nginx"
    [ -d /etc/apache2 ] && DIRS_TO_WATCH="${DIRS_TO_WATCH:+$DIRS_TO_WATCH,}/etc/apache2"
    [ -d /etc/httpd ] && DIRS_TO_WATCH="${DIRS_TO_WATCH:+$DIRS_TO_WATCH,}/etc/httpd"

    WATCH_DIRS="$DIRS_TO_WATCH"
fi

if [ -z "$WATCH_DIRS" ]; then
    WATCH_DIRS="/var/www"
    warn "No web directories found, defaulting to /var/www"
fi

log "Watch directories: $WATCH_DIRS"

# ═══════════════════════════════════════
# INSTALL DEPENDENCIES
# ═══════════════════════════════════════
step "Installing dependencies"

case $OS_NAME in
    ubuntu|debian)
        apt-get update -qq
        apt-get install -y -qq curl wget tar iptables ca-certificates >/dev/null 2>&1
        ;;
    almalinux|rocky|centos|rhel)
        yum install -y -q curl wget tar iptables ca-certificates >/dev/null 2>&1
        ;;
    *)
        warn "Unknown OS $OS_NAME — skipping package install"
        ;;
esac
log "Dependencies installed"

# ═══════════════════════════════════════
# DOWNLOAD HYDRA BINARY
# ═══════════════════════════════════════
step "Downloading HYDRA v${VERSION}"

mkdir -p "$HYDRA_DIR" /etc/hydra

# Download pre-built binary
BINARY_URL="${DOWNLOAD_URL}/hydra-${VERSION}-linux-${GO_ARCH}"
if curl -fsSL -o "$HYDRA_BIN" "$BINARY_URL" 2>/dev/null; then
    chmod +x "$HYDRA_BIN"
    log "Downloaded HYDRA binary"
else
    warn "Pre-built binary not available. Checking for Go compiler..."

    # Install Go if needed
    if ! command -v go &>/dev/null; then
        GO_VERSION="1.22.2"
        log "Installing Go ${GO_VERSION}..."
        curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz" -o /tmp/go.tar.gz
        rm -rf /usr/local/go
        tar -C /usr/local -xzf /tmp/go.tar.gz
        rm /tmp/go.tar.gz
        export PATH=$PATH:/usr/local/go/bin
        echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile.d/golang.sh
        log "Go ${GO_VERSION} installed"
    else
        log "Go already installed: $(go version)"
    fi

    # Build from source if available
    if [ -f "$HYDRA_DIR/go.mod" ]; then
        log "Building from source..."
        cd "$HYDRA_DIR"
        GONOSUMCHECK=* GONOSUMDB=* go build -ldflags="-s -w" -o "$HYDRA_BIN" ./cmd/sentinel/
        log "Built HYDRA binary: $(du -h $HYDRA_BIN | cut -f1)"
    else
        err "No binary available and no source code found in $HYDRA_DIR"
    fi
fi

# Verify binary
if [ ! -x "$HYDRA_BIN" ]; then
    err "HYDRA binary not found or not executable"
fi
BINARY_HASH=$($HYDRA_BIN --print-hash 2>/dev/null || sha256sum "$HYDRA_BIN" | cut -d' ' -f1)
log "Binary hash: ${BINARY_HASH:0:16}..."

# ═══════════════════════════════════════
# SETUP LICENSE
# ═══════════════════════════════════════
if [ -n "$LICENSE_KEY" ]; then
    step "Activating license"
    echo "$LICENSE_KEY" > /etc/hydra/license.key
    chmod 600 /etc/hydra/license.key
    log "License key saved"
fi

# ═══════════════════════════════════════
# CREATE SYSTEMD SERVICE
# ═══════════════════════════════════════
step "Creating systemd service"

# Generate unique deploy secret from binary hash
DEPLOY_SECRET="hydra-$(echo "$BINARY_HASH" | head -c 32)"

cat > /etc/systemd/system/hydra.service << SERVICEEOF
[Unit]
Description=HYDRA Self-Healing Security v${VERSION}
Documentation=https://hydrasecurity.dev
After=network.target

[Service]
Type=simple
User=root
Group=root
Environment="HYDRA_PARASITE_DISABLE=1"
ExecStartPre=/bin/rm -rf /opt/hydra/.shadow
ExecStart=${HYDRA_BIN} \\
    --watch ${WATCH_DIRS} \\
    --vault ${HYDRA_DIR}/vault-data \\
    --logs ${HYDRA_DIR}/logs \\
    --verbose \\
    --deploy-secret "${DEPLOY_SECRET}" \\
    --firewall --waf --process-guard --log-sentinel --cerberus --evo

Restart=always
RestartSec=2
StartLimitIntervalSec=60
StartLimitBurst=10

StandardOutput=journal
StandardError=journal
SyslogIdentifier=hydra

[Install]
WantedBy=multi-user.target
SERVICEEOF

chmod 644 /etc/systemd/system/hydra.service
systemctl daemon-reload
log "Systemd service created"

# ═══════════════════════════════════════
# CREATE DATA DIRECTORIES
# ═══════════════════════════════════════
mkdir -p "$HYDRA_DIR/vault-data" "$HYDRA_DIR/logs" "$HYDRA_DIR/hospital/backups"
chmod 700 "$HYDRA_DIR/vault-data" "$HYDRA_DIR/logs"

# ═══════════════════════════════════════
# START HYDRA
# ═══════════════════════════════════════
step "Starting HYDRA"

systemctl enable hydra >/dev/null 2>&1
systemctl start hydra

# Wait for startup
sleep 3

# Check if running
if systemctl is-active --quiet hydra; then
    log "HYDRA is running!"

    # Get status
    STATUS=$(curl -sk http://localhost:9876/status 2>/dev/null || curl -sk https://localhost:9877/status 2>/dev/null || echo '{}')
    LAYERS=$(echo "$STATUS" | python3 -c "import sys,json;print(json.load(sys.stdin).get('layers_active',0))" 2>/dev/null || echo "?")
    FILES=$(echo "$STATUS" | python3 -c "import sys,json;print(json.load(sys.stdin).get('files_protected',0))" 2>/dev/null || echo "?")

    echo ""
    echo -e "  ${GREEN}╔════════════════════════════════════════════════╗${NC}"
    echo -e "  ${GREEN}║   HYDRA v${VERSION} — INSTALLED AND RUNNING       ║${NC}"
    echo -e "  ${GREEN}╠════════════════════════════════════════════════╣${NC}"
    echo -e "  ${GREEN}║${NC}  Layers active:  ${BOLD}${LAYERS}${NC}                          ${GREEN}║${NC}"
    echo -e "  ${GREEN}║${NC}  Files protected: ${BOLD}${FILES}${NC}                        ${GREEN}║${NC}"
    echo -e "  ${GREEN}║${NC}  Panel:           ${BOLD}${PANEL}${NC}                       ${GREEN}║${NC}"
    echo -e "  ${GREEN}║${NC}  Web server:      ${BOLD}${WEBSERVER}${NC}                       ${GREEN}║${NC}"
    echo -e "  ${GREEN}║${NC}  OS:              ${BOLD}${OS_NAME} ${OS_VERSION}${NC}               ${GREEN}║${NC}"
    echo -e "  ${GREEN}╠════════════════════════════════════════════════╣${NC}"
    echo -e "  ${GREEN}║${NC}  Deploy secret:   ${YELLOW}${DEPLOY_SECRET:0:20}...${NC}       ${GREEN}║${NC}"
    echo -e "  ${GREEN}║${NC}  Status:          ${CYAN}curl localhost:9876/status${NC}  ${GREEN}║${NC}"
    echo -e "  ${GREEN}║${NC}  Logs:            ${CYAN}journalctl -u hydra -f${NC}      ${GREEN}║${NC}"
    echo -e "  ${GREEN}║${NC}  Dare:            ${CYAN}curl localhost:9876/dare${NC}    ${GREEN}║${NC}"
    echo -e "  ${GREEN}╠════════════════════════════════════════════════╣${NC}"
    echo -e "  ${GREEN}║${NC}  ${BOLD}\"Cut off a head, two grow back.\"${NC}              ${GREEN}║${NC}"
    echo -e "  ${GREEN}╚════════════════════════════════════════════════╝${NC}"
    echo ""
    echo -e "  ${CYAN}Dashboard:${NC} https://$(hostname -I | awk '{print $1}'):9877/dashboard"
    echo -e "  ${CYAN}Support:${NC}   https://hydrasecurity.dev"
    echo ""
else
    err "HYDRA failed to start. Check: journalctl -u hydra -n 50"
fi
