#!/usr/bin/env bash
# ==============================================================================
# AINAV Local Agent - Linux Automated Installer
# Usage:
#   curl -fsSL https://get.ainav.id/install.sh | sudo bash
# Atau dengan token langsung:
#   curl -fsSL https://get.ainav.id/install.sh | sudo AINAV_AGENT_TOKEN="xyz" bash
# ==============================================================================

set -euo pipefail

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

echo -e "${BLUE}======================================================${NC}"
echo -e "${BLUE}        AINAV Local Agent - Installer (Linux)         ${NC}"
echo -e "${BLUE}======================================================${NC}"

# 1. Pastikan dijalankan sebagai root (sudo)
if [ "$(id -u)" -ne 0 ]; then
    echo -e "${RED}[!] Skrip ini memerlukan hak akses root.${NC}"
    echo -e "    Silakan jalankan: sudo bash $0 atau curl ... | sudo bash"
    exit 1
fi

DIST_URL="${AINAV_DIST_URL:-https://get.ainav.id}"
BASE_DIR="/opt/ainav"
BIN_DIR="${BASE_DIR}/bin"
ETC_DIR="${BASE_DIR}/etc"
LOG_DIR="${BASE_DIR}/log"
DATA_DIR="${BASE_DIR}/data"
TMP_DIR="${BASE_DIR}/tmp"
CONF_FILE="${ETC_DIR}/agent.conf"
SERVICE_FILE="/etc/systemd/system/ainav-agent.service"

# 2. Cek dependensi dasar (curl, tar, python3, systemd)
echo -e "[*] Memeriksa dependensi sistem..."
for cmd in curl tar python3 systemctl; do
    if ! command -v "$cmd" &>/dev/null; then
        echo -e "${YELLOW}[*] Menginstall dependensi: $cmd ...${NC}"
        if command -v apt-get &>/dev/null; then
            apt-get update -qq && apt-get install -y -qq "$cmd"
        elif command -v yum &>/dev/null; then
            yum install -y -q "$cmd"
        elif command -v dnf &>/dev/null; then
            dnf install -y -q "$cmd"
        else
            echo -e "${RED}[!] Package manager tidak didukung secara otomatis. Silakan install '$cmd' secara manual.${NC}"
            exit 1
        fi
    fi
done

# 3. Setup direktori FHS
echo -e "[*] Menyiapkan direktori di ${BASE_DIR} ..."
mkdir -p "${BIN_DIR}" "${ETC_DIR}" "${LOG_DIR}" "${DATA_DIR}" "${TMP_DIR}"
chmod 755 "${BASE_DIR}" "${BIN_DIR}"
chmod 700 "${DATA_DIR}" "${TMP_DIR}"

# 4. Tanamkan Public Key Ed25519 untuk verifikasi integritas pembaruan
PUB_KEY_FILE="${ETC_DIR}/release_public.pem"
cat << 'EOF' > "${PUB_KEY_FILE}"
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA/xd8cdqchUSYOQrduj3gHmno78rxGLTzuPBmGmF8H4c=
-----END PUBLIC KEY-----
EOF
chmod 644 "${PUB_KEY_FILE}"

# 5. Cek token atau minta input interaktif dari terminal (/dev/tty)
TOKEN="${AINAV_AGENT_TOKEN:-${AINAV_TOKEN:-}}"
if [ -z "${TOKEN}" ]; then
    EXISTING_TOKEN=""
    if [ -e "${CONF_FILE}" ]; then
        EXISTING_TOKEN=$(grep -E "^AINAV_AGENT_TOKEN=" "${CONF_FILE}" | head -n1 | cut -d'=' -f2- | tr -d '"' || true)
    fi

    # Jika dijalankan via pipe (curl ... | sudo bash), stdin dialihkan,
    # sehingga prompt interaktif dibaca langsung dari controlling terminal (/dev/tty)
    if [ -r /dev/tty ] && [ -w /dev/tty ]; then
        if [ -n "${EXISTING_TOKEN}" ]; then
            echo -en "${YELLOW}[?] Masukkan AINAV_AGENT_TOKEN (Tekan ENTER untuk mempertahankan token lama): ${NC}" > /dev/tty
            read -r INPUT_TOKEN < /dev/tty
            TOKEN="${INPUT_TOKEN:-${EXISTING_TOKEN}}"
        else
            echo -en "${YELLOW}[?] Masukkan AINAV_AGENT_TOKEN dari dashboard AINAV: ${NC}" > /dev/tty
            read -r TOKEN < /dev/tty
        fi
        echo "" > /dev/tty
    elif [ -t 0 ]; then
        if [ -n "${EXISTING_TOKEN}" ]; then
            echo -en "${YELLOW}[?] Masukkan AINAV_AGENT_TOKEN (Tekan ENTER untuk mempertahankan token lama): ${NC}"
            read -r INPUT_TOKEN
            TOKEN="${INPUT_TOKEN:-${EXISTING_TOKEN}}"
        else
            echo -en "${YELLOW}[?] Masukkan AINAV_AGENT_TOKEN dari dashboard AINAV: ${NC}"
            read -r TOKEN
        fi
        echo ""
    elif [ -n "${EXISTING_TOKEN}" ]; then
        echo -e "[*] Berkas konfigurasi sudah ada, mempertahankan token lama..."
        TOKEN="${EXISTING_TOKEN}"
    else
        echo -e "${YELLOW}[!] Mode non-interaktif terdeteksi. Token dapat diisi nanti di ${CONF_FILE}.${NC}"
        TOKEN=""
    fi
fi

# 6. Unduh manifest & rilis paket terbaru
echo -e "[*] Mengunduh informasi rilis dari ${DIST_URL}/version.json ..."
MANIFEST=$(curl -fsSL "${DIST_URL}/version.json")
TAR_URL=$(echo "${MANIFEST}" | python3 -c "import sys, json; data=json.load(sys.stdin); print(data['platforms']['linux_x86_64']['url'])")
EXPECTED_SHA=$(echo "${MANIFEST}" | python3 -c "import sys, json; data=json.load(sys.stdin); print(data['platforms']['linux_x86_64']['sha256'])")

echo -e "[*] Mengunduh paket agen dari ${TAR_URL} ..."
curl -fsSL -o "${TMP_DIR}/agent.tar.gz" "${TAR_URL}"

# Verifikasi SHA256
echo -e "[*] Memverifikasi integritas checksum SHA256..."
CALC_SHA=$(sha256sum "${TMP_DIR}/agent.tar.gz" | awk '{print $1}')
if [ "${CALC_SHA}" != "${EXPECTED_SHA}" ]; then
    echo -e "${RED}[!] Checksum SHA256 tidak cocok! Paket mungkin rusak atau diubah.${NC}"
    echo -e "    Diharapkan: ${EXPECTED_SHA}"
    echo -e "    Diterima:   ${CALC_SHA}"
    rm -rf "${TMP_DIR}/agent.tar.gz"
    exit 1
fi
echo -e "${GREEN}[+] Checksum SHA256 valid.${NC}"

# Ekstrak biner/agen
echo -e "[*] Mengekstrak paket ke ${BIN_DIR} ..."
tar -xzf "${TMP_DIR}/agent.tar.gz" -C "${TMP_DIR}"
rm -rf "${BIN_DIR:?}"/*
cp -r "${TMP_DIR}/agent"/* "${BIN_DIR}/"
rm -rf "${TMP_DIR}/agent" "${TMP_DIR}/agent.tar.gz"

# 7. Setup Virtual Environment Python jika belum ada
if [ ! -d "${BASE_DIR}/venv" ]; then
    echo -e "[*] Menyiapkan isolated Python virtualenv..."
    python3 -m venv "${BASE_DIR}/venv"
fi
echo -e "[*] Memastikan dependencies python terinstall..."
"${BASE_DIR}/venv/bin/pip" install --quiet --upgrade pip
if [ -f "${BIN_DIR}/requirements.txt" ]; then
    "${BASE_DIR}/venv/bin/pip" install --quiet -r "${BIN_DIR}/requirements.txt"
fi

# Buat launcher script executable di /usr/local/bin/ainav-agent
cat << EOF > /usr/local/bin/ainav-agent
#!/usr/bin/env bash
exec ${BASE_DIR}/venv/bin/python3 ${BIN_DIR}/main.py "\$@"
EOF
chmod +x /usr/local/bin/ainav-agent

# 8. Tulis / Update file konfigurasi (chmod 600 untuk zero credential leak)
if [ ! -f "${CONF_FILE}" ] || [ -n "${TOKEN}" ]; then
    echo -e "[*] Menulis konfigurasi aman ke ${CONF_FILE} (chmod 600) ..."
    cat << EOF > "${CONF_FILE}"
# ==============================================================================
# AINAV Local Agent Configuration
# Hak akses ketat (chmod 600) - Hanya root yang boleh membaca
# ==============================================================================

# Use a dedicated token for this device.
AINAV_AGENT_TOKEN="${TOKEN}"

# Job control plane and runtime backend are intentionally separate.
AINAV_CONTROL_PLANE="https://agent.it-indonesia.com"
AINAV_BACKEND_URL="https://xyz.ainav.id"

AINAV_FETCH_JOB_PATH="/agent/fetch-job"
AINAV_REPORT_PATH="/agent/report"
AINAV_REGISTER_PATH="/api/v1/agent-runtime/register"
AINAV_HEARTBEAT_PATH="/api/v1/agent-runtime/heartbeat"
AINAV_RELEASE_PATH="/api/v1/agent-runtime/release"
AINAV_MONITORING_FETCH_PATH="/api/v1/agent-runtime/monitoring/fetch"
AINAV_MONITORING_REPORT_PATH="/api/v1/agent-runtime/monitoring/report"

AINAV_WS_MONITORING_URL="wss://monitoring.ainav.id/ws/agent"
AINAV_WS_MONITORING_ENABLED="true"
AINAV_WS_METRICS_TICK_INTERVAL="1"
AINAV_WS_DIAGNOSTIC_SNAPSHOT_INTERVAL="60"
AINAV_WS_ALERT_COOLDOWN_SECONDS="300"

AINAV_HEARTBEAT_INTERVAL="30"
AINAV_RUNTIME_METRICS_INTERVAL="30"
AINAV_METRICS_INTERVAL="10"
AINAV_MONITORING_RETENTION_DAYS="7"
AINAV_RETENTION_HOURS="72"

AINAV_ALERT_MEMORY="90"
AINAV_ALERT_CPU="90"
AINAV_ALERT_DISK="95"
AINAV_LOCAL_UI_ENABLED="false"

AINAV_HARDWARE_SENSOR_ENABLED="true"
AINAV_HARDWARE_SENSOR_URL="http://192.168.10.99:9100/sensors"
AINAV_HARDWARE_SENSOR_TIMEOUT_SECONDS="3"
AINAV_HARDWARE_SENSOR_REFRESH_SECONDS="30"
AINAV_HARDWARE_SENSOR_STALE_SECONDS="300"
AINAV_HARDWARE_SENSOR_MAX_RESPONSE_KB="128"
AINAV_HARDWARE_SENSOR_MAX_SENSORS="128"
EOF
    chmod 600 "${CONF_FILE}"

    # Buat symlink .env agar eksekusi langsung via CLI / Python membaca konfigurasi yang sama
    ln -sf "${CONF_FILE}" "${BASE_DIR}/.env"
    ln -sf "${CONF_FILE}" "${BIN_DIR}/.env"
fi

# 9. Daftarkan Systemd Service
echo -e "[*] Mendaftarkan Systemd Service (${SERVICE_FILE}) ..."
cat << 'EOF' > "${SERVICE_FILE}"
[Unit]
Description=AINAV Infrastructure Monitoring Agent
After=network.target network-online.target systemd-time-wait-sync.service
Wants=network-online.target

[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/opt/ainav
EnvironmentFile=-/opt/ainav/etc/agent.conf
ExecStart=/usr/local/bin/ainav-agent run
Restart=always
RestartSec=5s

# Resource Governance Aman (Mencegah runaway memory tanpa membatasi CPU)
MemoryHigh=256M
MemoryMax=512M
CPUWeight=100

# Security Hardening
ProtectSystem=full
PrivateTmp=true

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=ainav-agent

[Install]
WantedBy=multi-user.target
EOF

# Reload & Jalankan Systemd
systemctl daemon-reload
systemctl enable ainav-agent.service
systemctl restart ainav-agent.service

echo -e "${GREEN}======================================================${NC}"
echo -e "${GREEN}[+] AINAV Local Agent berhasil diinstall dan berjalan!${NC}"
echo -e "    Status Servis : sudo systemctl status ainav-agent"
echo -e "    Diagnostik    : sudo ainav-agent --doctor"
echo -e "    Log Servis    : sudo journalctl -u ainav-agent -f"
echo -e "${GREEN}======================================================${NC}"
