#!/bin/sh
# ═══════════════════════════════════════════════════════════════════════════════
#  NZBHydra2 Controller - Usenet Meta Search
#  LXC container with Debian rootfs (no Docker/Podman)
# ═══════════════════════════════════════════════════════════════════════════════

CONTAINER_NAME="nzbhydra"
CONTAINER_DIR="/srv/lxc/$CONTAINER_NAME"
DATA_DIR="/srv/nzbhydra"
CONFIG="nzbhydra"

# Debian LXC rootfs URL (arm64) - Linux Containers official
DEBIAN_LXC_MIRROR="https://images.linuxcontainers.org/images/debian/bookworm/arm64/default"

# Logging
log_info() { logger -t nzbhydra -p user.info "$*"; echo "[INFO] $*"; }
log_error() { logger -t nzbhydra -p user.error "$*"; echo "[ERROR] $*" >&2; }
log_ok() { echo "[OK] $*"; }

# UCI helpers
uci_get() { uci -q get "$CONFIG.$1"; }

# ─────────────────────────────────────────────────────────────────────────────────
# Install container with Debian rootfs
# ─────────────────────────────────────────────────────────────────────────────────
cmd_install() {
    log_info "Installing NZBHydra2 container (Debian LXC)..."

    # Create directories
    mkdir -p "$CONTAINER_DIR/rootfs"
    mkdir -p "$DATA_DIR/config"

    local rootfs="$CONTAINER_DIR/rootfs"

    # Download Debian LXC rootfs if not exists
    if [ ! -f "$rootfs/bin/bash" ]; then
        log_info "Downloading Debian LXC rootfs..."

        # Get latest build date from LXC mirror
        local latest=$(curl -sL "$DEBIAN_LXC_MIRROR/" | grep -oE '[0-9]{8}_[0-9]{2}:[0-9]{2}' | sort -r | head -1)
        [ -z "$latest" ] && latest="20240301_05:24"

        local rootfs_url="${DEBIAN_LXC_MIRROR}/${latest}/rootfs.tar.xz"
        local tarball="/tmp/debian-rootfs-nzbhydra.tar.xz"

        log_info "Fetching: $rootfs_url"
        curl -L -o "$tarball" "$rootfs_url" || {
            log_error "Failed to download Debian rootfs"
            return 1
        }

        log_info "Extracting rootfs..."
        xz -d -c "$tarball" | tar -xf - -C "$rootfs" || {
            log_error "Failed to extract rootfs"
            rm -f "$tarball"
            return 1
        }
        rm -f "$tarball"
    fi

    # Configure DNS
    echo "nameserver 8.8.8.8" > "$rootfs/etc/resolv.conf"
    echo "nameserver 1.1.1.1" >> "$rootfs/etc/resolv.conf"

    # Create startup script
    cat > "$rootfs/start-nzbhydra.sh" <<'STARTEOF'
#!/bin/bash
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export HOME="/root"
exec > /config/startup.log 2>&1

echo "=== Starting NZBHydra2 $(date) ==="

# Install NZBHydra2 if not present
if [ ! -f "/opt/nzbhydra2/lib/core.jar" ] && ! ls /opt/nzbhydra2/lib/core-*-exec.jar >/dev/null 2>&1; then
    echo "Installing NZBHydra2..."

    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        openjdk-17-jre-headless \
        python3 \
        curl \
        ca-certificates \
        unzip || { echo "apt install failed"; exit 1; }

    # Download NZBHydra2
    mkdir -p /opt/nzbhydra2
    cd /opt/nzbhydra2

    echo "Downloading NZBHydra2..."
    latest=$(curl -sL "https://api.github.com/repos/theotherp/nzbhydra2/releases/latest" | grep -oP "\"tag_name\": \"v\K[^\"]+")
    [ -z "$latest" ] && latest="8.5.2"

    echo "Version: $latest"
    curl -L -o nzbhydra2.zip "https://github.com/theotherp/nzbhydra2/releases/download/v${latest}/nzbhydra2-${latest}-generic.zip"

    unzip -o nzbhydra2.zip || { echo "unzip failed"; exit 1; }
    rm -f nzbhydra2.zip
    chmod +x nzbhydra2wrapperPy3.py 2>/dev/null || true

    apt-get clean
    rm -rf /var/lib/apt/lists/*
else
    echo "NZBHydra2 already installed"
    # Ensure python3 is installed
    if ! command -v python3 >/dev/null 2>&1; then
        apt-get update
        DEBIAN_FRONTEND=noninteractive apt-get install -y python3
        apt-get clean
    fi
fi

echo "=== Starting NZBHydra2 server ==="
mkdir -p /config
cd /opt/nzbhydra2
exec python3 nzbhydra2wrapperPy3.py --nobrowser --datafolder /config --host 0.0.0.0 --port 5076
STARTEOF
    chmod +x "$rootfs/start-nzbhydra.sh"

    # Create LXC config
    local memory=$(uci_get main.memory)
    [ -z "$memory" ] && memory="268435456"  # 256MB in bytes

    cat > "$CONTAINER_DIR/config" <<EOF
lxc.uts.name = $CONTAINER_NAME
lxc.rootfs.path = dir:$CONTAINER_DIR/rootfs
lxc.init.cmd = /start-nzbhydra.sh

# Network - use veth with bridge
lxc.net.0.type = veth
lxc.net.0.link = br-lan
lxc.net.0.flags = up
lxc.net.0.ipv4.address = 192.168.255.41/24
lxc.net.0.ipv4.gateway = 192.168.255.1

# Mounts
lxc.mount.auto = proc:mixed sys:ro
lxc.mount.entry = $DATA_DIR/config config none bind,create=dir 0 0
lxc.mount.entry = tmpfs tmp tmpfs defaults 0 0
lxc.mount.entry = tmpfs run tmpfs defaults 0 0

# Capabilities
lxc.cap.drop = sys_admin sys_boot sys_module sys_rawio sys_time

# Memory limit
lxc.cgroup2.memory.max = $memory

# TTY
lxc.tty.max = 0
lxc.pty.max = 256

# Seccomp (disabled for compatibility)
lxc.seccomp.profile =

# Auto-start
lxc.start.auto = 1
EOF

    log_ok "NZBHydra2 container installed"
    log_info "Container IP: 192.168.255.41"
    log_info "Run: nzbhydractl start"
}

# ─────────────────────────────────────────────────────────────────────────────────
# Start container
# ─────────────────────────────────────────────────────────────────────────────────
cmd_start() {
    if ! [ -d "$CONTAINER_DIR/rootfs" ]; then
        log_error "Container not installed. Run: nzbhydractl install"
        return 1
    fi

    if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
        log_info "NZBHydra2 already running"
        return 0
    fi

    log_info "Starting NZBHydra2..."
    lxc-start -n "$CONTAINER_NAME" -f "$CONTAINER_DIR/config"

    # Wait for startup
    sleep 5
    if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
        log_ok "NZBHydra2 started on http://192.168.255.41:5076/"
    else
        log_error "Failed to start NZBHydra2"
        lxc-info -n "$CONTAINER_NAME" 2>&1
        return 1
    fi
}

# ─────────────────────────────────────────────────────────────────────────────────
# Stop container
# ─────────────────────────────────────────────────────────────────────────────────
cmd_stop() {
    if ! lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
        log_info "NZBHydra2 not running"
        return 0
    fi

    log_info "Stopping NZBHydra2..."
    lxc-stop -n "$CONTAINER_NAME" -t 30
    log_ok "NZBHydra2 stopped"
}

# ─────────────────────────────────────────────────────────────────────────────────
# Restart container
# ─────────────────────────────────────────────────────────────────────────────────
cmd_restart() {
    cmd_stop
    sleep 2
    cmd_start
}

# ─────────────────────────────────────────────────────────────────────────────────
# Status
# ─────────────────────────────────────────────────────────────────────────────────
cmd_status() {
    echo "=== NZBHydra2 Status ==="

    # Container state
    if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
        echo "Container: RUNNING"
        echo "IP: 192.168.255.41"
    else
        echo "Container: STOPPED"
        return 0
    fi

    # Check if API responds
    if curl -s "http://192.168.255.41:5076/api?t=caps" >/dev/null 2>&1; then
        echo "API: OK"
    else
        echo "API: Not responding (may be starting)"
    fi

    echo "Web UI: http://192.168.255.41:5076/"
}

# ─────────────────────────────────────────────────────────────────────────────────
# Logs
# ─────────────────────────────────────────────────────────────────────────────────
cmd_logs() {
    local lines="${1:-50}"
    if [ -f "$DATA_DIR/config/logs/nzbhydra2.log" ]; then
        tail -n "$lines" "$DATA_DIR/config/logs/nzbhydra2.log"
    elif [ -f "$DATA_DIR/config/startup.log" ]; then
        tail -n "$lines" "$DATA_DIR/config/startup.log"
    else
        log_info "No logs yet. NZBHydra may not have run."
    fi
}

# ─────────────────────────────────────────────────────────────────────────────────
# Shell access
# ─────────────────────────────────────────────────────────────────────────────────
cmd_shell() {
    if ! lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
        log_error "Container not running"
        return 1
    fi
    lxc-attach -n "$CONTAINER_NAME" -- /bin/bash
}

# ─────────────────────────────────────────────────────────────────────────────────
# Link SABnzbd as downloader
# ─────────────────────────────────────────────────────────────────────────────────
cmd_link_sabnzbd() {
    log_info "Linking SABnzbd..."

    # Get SABnzbd API key
    local sab_ini="/srv/sabnzbd/config/sabnzbd.ini"
    if [ ! -f "$sab_ini" ]; then
        log_error "SABnzbd not configured. Start SABnzbd first."
        return 1
    fi

    local sab_api=$(grep "^api_key" "$sab_ini" 2>/dev/null | cut -d'=' -f2 | tr -d ' ')

    if [ -z "$sab_api" ]; then
        log_error "SABnzbd API key not found. Configure SABnzbd first."
        return 1
    fi

    # Update UCI
    uci set "nzbhydra.sabnzbd.host=http://192.168.255.40:8085"
    uci set "nzbhydra.sabnzbd.api_key=$sab_api"
    uci commit nzbhydra

    log_ok "SABnzbd linked: http://192.168.255.40:8085"
    log_info "Configure in NZBHydra web UI: http://192.168.255.41:5076/"
}

# ─────────────────────────────────────────────────────────────────────────────────
# Search
# ─────────────────────────────────────────────────────────────────────────────────
cmd_search() {
    local query="$1"
    [ -z "$query" ] && { log_error "Usage: nzbhydractl search <query>"; return 1; }

    log_info "Searching: $query"

    local result=$(curl -s "http://192.168.255.41:5076/api?t=search&q=$(echo "$query" | sed 's/ /%20/g')" 2>/dev/null)

    if [ -n "$result" ]; then
        echo "$result" | python3 -c "
import sys, xml.etree.ElementTree as ET
xml = sys.stdin.read()
try:
    root = ET.fromstring(xml)
    items = root.findall('.//item')
    for i, item in enumerate(items[:10], 1):
        title = item.find('title').text if item.find('title') is not None else 'N/A'
        size = item.find('enclosure').get('length', '0') if item.find('enclosure') is not None else '0'
        size_mb = int(size) // (1024*1024)
        print(f'{i}. {title} ({size_mb} MB)')
except Exception as e:
    print(f'Error parsing: {e}')
" 2>/dev/null
    else
        log_error "Search failed or no results"
    fi
}

# ─────────────────────────────────────────────────────────────────────────────────
# Configure HAProxy exposure
# ─────────────────────────────────────────────────────────────────────────────────
cmd_configure_haproxy() {
    local domain=$(uci_get exposure.domain)
    [ -z "$domain" ] && domain="nzbhydra.gk2.secubox.in"

    log_info "Configuring HAProxy for $domain"

    # Create backend
    uci set haproxy.nzbhydra_web=backend
    uci set haproxy.nzbhydra_web.name='nzbhydra_web'
    uci set haproxy.nzbhydra_web.mode='http'
    uci set haproxy.nzbhydra_web.server="nzbhydra 192.168.255.41:5076 weight 100 check"

    # Create vhost
    local vhost_id=$(echo "$domain" | tr '.' '_')
    uci set "haproxy.$vhost_id=vhost"
    uci set "haproxy.$vhost_id.domain=$domain"
    uci set "haproxy.$vhost_id.backend=mitmproxy_inspector"
    uci set "haproxy.$vhost_id.original_backend=nzbhydra_web"
    uci set "haproxy.$vhost_id.ssl=1"
    uci set "haproxy.$vhost_id.ssl_redirect=1"
    uci set "haproxy.$vhost_id.acme=1"
    uci commit haproxy

    # Add mitmproxy route
    if [ -f /srv/mitmproxy/haproxy-routes.json ]; then
        python3 -c "
import json
with open('/srv/mitmproxy/haproxy-routes.json') as f:
    routes = json.load(f)
routes['$domain'] = ['192.168.255.41', 5076]
with open('/srv/mitmproxy/haproxy-routes.json', 'w') as f:
    json.dump(routes, f, indent=2)
" 2>/dev/null
    fi

    # Reload
    haproxyctl reload 2>/dev/null || true
    /etc/init.d/mitmproxy restart 2>/dev/null || true

    log_ok "HAProxy configured: https://$domain/"
}

# ─────────────────────────────────────────────────────────────────────────────────
# Uninstall
# ─────────────────────────────────────────────────────────────────────────────────
cmd_uninstall() {
    log_info "Uninstalling NZBHydra2..."

    cmd_stop 2>/dev/null

    rm -rf "$CONTAINER_DIR"
    log_info "Container removed. Data preserved in $DATA_DIR"

    log_ok "NZBHydra2 uninstalled"
}

# ─────────────────────────────────────────────────────────────────────────────────
# Main
# ─────────────────────────────────────────────────────────────────────────────────
case "$1" in
    install)    cmd_install ;;
    start)      cmd_start ;;
    stop)       cmd_stop ;;
    restart)    cmd_restart ;;
    status)     cmd_status ;;
    logs)       shift; cmd_logs "$@" ;;
    shell)      cmd_shell ;;
    search)     shift; cmd_search "$@" ;;
    link-sabnzbd) cmd_link_sabnzbd ;;
    configure-haproxy) cmd_configure_haproxy ;;
    uninstall)  cmd_uninstall ;;
    *)
        echo "NZBHydra2 Controller - Usenet Meta Search"
        echo ""
        echo "Usage: nzbhydractl <command>"
        echo ""
        echo "Commands:"
        echo "  install           Install Debian LXC container with NZBHydra2"
        echo "  start             Start NZBHydra2"
        echo "  stop              Stop NZBHydra2"
        echo "  restart           Restart NZBHydra2"
        echo "  status            Show status"
        echo "  logs [n]          Show last n log lines (default 50)"
        echo "  shell             Interactive shell in container"
        echo "  search <query>    Search indexers"
        echo "  link-sabnzbd      Configure SABnzbd as downloader"
        echo "  configure-haproxy Setup HAProxy reverse proxy"
        echo "  uninstall         Remove container (keeps data)"
        ;;
esac
