#!/usr/bin/env bash
set -euo pipefail

####################################################################
# Koro ERP — Native Binary Installer (Linux / macOS)
#
# Installs all Koro ERP services as native binaries — NO DOCKER.
# Each service becomes a systemd unit (Linux) or launchd agent (macOS).
#
# Usage — one-liner from the website:
#   curl -fsSL https://YOUR_DOMAIN/deploy/install-binaries.sh | bash
#
# Override the mirror hosting the binaries (default: same origin):
#   curl -fsSL .../install-binaries.sh | KORO_BINARY_MIRROR=https://cdn.example.com/binaries bash
#
# Non-interactive install:
#   curl -fsSL .../install-binaries.sh | KORO_NONINTERACTIVE=1 KORO_DB_HOST=db.local bash
#
# Environment overrides (all optional):
#   KORO_INSTALL_DIR      /opt/koro-erp
#   KORO_USER             koro
#   KORO_BINARY_MIRROR    https://koroworks.com/binaries
#   KORO_DB_HOST          localhost
#   KORO_DB_PORT          5432
#   KORO_DB_USER          postgres
#   KORO_DB_PASSWORD      (prompted)
#   KORO_GATEWAY_PORT     7009
#   KORO_PLATFORM_API_URL (Platform API URL for install enrollment)
#   KORO_ENROLLMENT_TOKEN (one-time token issued by Platform APIs)
####################################################################

# ── Config ───────────────────────────────────────────────────────
BASE_URL="${KORO_BINARY_MIRROR:-https://koroworks.com/binaries}"
INSTALL_DIR="${KORO_INSTALL_DIR:-/opt/koro-erp}"
SERVICE_USER="${KORO_USER:-koro}"
DB_HOST="${KORO_DB_HOST:-localhost}"
DB_PORT="${KORO_DB_PORT:-5432}"
DB_USER="${KORO_DB_USER:-postgres}"
DB_PASSWORD="${KORO_DB_PASSWORD:-}"
GATEWAY_PORT="${KORO_GATEWAY_PORT:-7009}"
PLATFORM_API_URL="${KORO_PLATFORM_API_URL:-https://platform-api.koroworks.com}"
ENROLLMENT_TOKEN="${KORO_ENROLLMENT_TOKEN:-}"

# ── Colours ──────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; BOLD='\033[1m'; NC='\033[0m'
info()  { echo -e "${BLUE}[INFO]${NC}  $*"; }
ok()    { echo -e "${GREEN}  [OK]${NC}  $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC}  $*"; }
fail()  { echo -e "${RED}[FAIL]${NC}  $*"; exit 1; }

# ── Banner ───────────────────────────────────────────────────────
echo ""
echo -e "${BOLD}${BLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}${BLUE}║       Koro ERP — Native Binary Installer (no Docker)     ║${NC}"
echo -e "${BOLD}${BLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""

# ── OS / arch detection ──────────────────────────────────────────
OS_KERNEL=$(uname -s)
case "$OS_KERNEL" in
  Linux)  OS=linux;   ARCHIVE_EXT=tar.gz ;;
  Darwin) OS=macos;   ARCHIVE_EXT=tar.gz ;;
  *) fail "Unsupported OS: $OS_KERNEL (use install-binaries.ps1 on Windows)" ;;
esac

MACHINE=$(uname -m)
case "$MACHINE" in
  x86_64|amd64) ARCH=amd64 ;;
  arm64|aarch64) ARCH=arm64 ;;
  *) fail "Unsupported architecture: $MACHINE" ;;
esac

info "Target: $OS/$ARCH"
info "Mirror: $BASE_URL"
info "Install dir: $INSTALL_DIR"

# ── Root check ───────────────────────────────────────────────────
if [ "$(id -u)" -ne 0 ]; then
  fail "Please run as root (or with sudo). Needed for systemd/launchd units and $INSTALL_DIR."
fi

# ── Prereqs ──────────────────────────────────────────────────────
for cmd in curl tar openssl; do
  command -v "$cmd" >/dev/null 2>&1 || fail "Missing required command: $cmd"
done
ok "Prerequisites present"

# ── Fetch VERSION ────────────────────────────────────────────────
VERSION=$(curl -fsSL "$BASE_URL/VERSION" | tr -d '[:space:]')
[ -n "$VERSION" ] || fail "Could not read $BASE_URL/VERSION"
ok "Release version: $VERSION"

# ── Service list (name:port) ─────────────────────────────────────
# Order matters: infrastructure-like deps first, gateway last.
SERVICES=(
  "party:7029"
  "auth:7000"
  "lookups:7019"
  "hrm:7001"
  "notifications:7002"
  "scm:7003"
  "manufacturing:7004"
  "crm:7005"
  "sales:7006"
  "project-management:7007"
  "accounting:7008"
  "logs:7010"
  "ecommerce:7011"
  "pos:7012"
  "payment-gateway:7013"
  "documents:7014"
  "marketing:7015"
  "compliance:7016"
  "agriculture:7017"
  "construction:7018"
  "ngo:7020"
  "logistics:7021"
  "healthcare:7022"
  "hotel:7032"
  "lms:7023"
  "chat:7024"
  "licence:7026"
  "service-desk:7027"
  "bsc:7028"
  "monitor:8010"
  "gateway:7009"
)

# ── Interactive prompts ──────────────────────────────────────────
if [ -z "${KORO_NONINTERACTIVE:-}" ]; then
  echo ""
  echo -e "${BOLD}Database configuration${NC}"
  read -rp "  PostgreSQL host [$DB_HOST]: " ans; DB_HOST=${ans:-$DB_HOST}
  read -rp "  PostgreSQL port [$DB_PORT]: " ans; DB_PORT=${ans:-$DB_PORT}
  read -rp "  PostgreSQL user [$DB_USER]: " ans; DB_USER=${ans:-$DB_USER}
  if [ -z "$DB_PASSWORD" ]; then
    read -rsp "  PostgreSQL password: " DB_PASSWORD; echo
  fi
  echo ""
fi

# ── Create service user (Linux only) ─────────────────────────────
if [ "$OS" = "linux" ]; then
  if ! id "$SERVICE_USER" >/dev/null 2>&1; then
    useradd --system --home "$INSTALL_DIR" --shell /usr/sbin/nologin "$SERVICE_USER"
    ok "Created system user: $SERVICE_USER"
  fi
fi

# ── Layout ───────────────────────────────────────────────────────
mkdir -p "$INSTALL_DIR"/{bin,keys,etc,logs,data}
cd "$INSTALL_DIR"

# ── Generate RSA keys if absent ──────────────────────────────────
if [ ! -f keys/private.pem ]; then
  openssl genpkey -algorithm RSA -out keys/private.pem -pkeyopt rsa_keygen_bits:2048 2>/dev/null
  openssl rsa -pubout -in keys/private.pem -out keys/public.pem 2>/dev/null
  chmod 600 keys/private.pem
  ok "Generated RSA key pair in $INSTALL_DIR/keys"
fi

# ── Generate .env if absent ──────────────────────────────────────
if [ ! -f etc/koro.env ]; then
  JWT_SECRET=$(openssl rand -base64 48 | tr -d '\n=+/' | cut -c1-48)
  ERP_SERVICE_TOKEN=$(openssl rand -base64 32 | tr -d '\n=+/' | cut -c1-32)
  cat > etc/koro.env <<EOF
# Koro ERP — global environment for all systemd services
# Generated by install-binaries.sh on $(date -u +%FT%TZ)

DB_HOST=$DB_HOST
DB_PORT=$DB_PORT
DB_USER=$DB_USER
DB_PASSWORD=$DB_PASSWORD
DB_SSLMODE=disable

JWT_SECRET_KEY=$JWT_SECRET
ERP_SERVICE_TOKEN=$ERP_SERVICE_TOKEN
PLATFORM_API_URL=$PLATFORM_API_URL
MARKETING_BASE_URL=${KORO_MARKETING_BASE_URL:-https://koroworks.com}
ENROLLMENT_TOKEN=$ENROLLMENT_TOKEN
INSTALL_MTLS_REQUIRED=${KORO_INSTALL_MTLS_REQUIRED:-false}
INSTALL_CLIENT_CERT=${KORO_INSTALL_CLIENT_CERT:-}
INSTALL_CLIENT_KEY=${KORO_INSTALL_CLIENT_KEY:-}
INSTALL_CA_BUNDLE=${KORO_INSTALL_CA_BUNDLE:-}

KEYS_DIR=$INSTALL_DIR/keys
DATA_DIR=$INSTALL_DIR/data
LOGS_DIR=$INSTALL_DIR/logs

PARTY_SERVICE_URL=http://127.0.0.1:7029

GATEWAY_PORT=$GATEWAY_PORT
CORS_ALLOWED_ORIGINS=*
EOF
  chmod 640 etc/koro.env
  ok "Wrote $INSTALL_DIR/etc/koro.env"
else
  info "Preserving existing $INSTALL_DIR/etc/koro.env"
fi

# ── Download all binaries ────────────────────────────────────────
echo ""
info "Downloading $((${#SERVICES[@]})) service binaries for $OS/$ARCH…"
for entry in "${SERVICES[@]}"; do
  name="${entry%%:*}"
  archive="koro-${name}-${VERSION}-${OS}-${ARCH}.${ARCHIVE_EXT}"
  url="$BASE_URL/$OS/$ARCH/$archive"
  tmp="/tmp/$archive"

  printf "  · %-22s " "$name"
  if curl -fsSL "$url" -o "$tmp"; then
    tar -xzf "$tmp" -C "$INSTALL_DIR/bin"
    chmod +x "$INSTALL_DIR/bin/koro-${name}"
    rm -f "$tmp"
    echo -e "${GREEN}✓${NC}"
  else
    echo -e "${RED}✗ (skipped — not published yet)${NC}"
  fi
done

# ── Ownership ────────────────────────────────────────────────────
if [ "$OS" = "linux" ]; then
  chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
fi

# ── systemd units (Linux) ────────────────────────────────────────
if [ "$OS" = "linux" ]; then
  info "Installing systemd units under /etc/systemd/system/…"
  for entry in "${SERVICES[@]}"; do
    name="${entry%%:*}"
    port="${entry##*:}"
    bin="$INSTALL_DIR/bin/koro-${name}"
    [ -x "$bin" ] || continue

    cat > "/etc/systemd/system/koro-${name}.service" <<EOF
[Unit]
Description=Koro ERP — ${name} (port ${port})
After=network-online.target
Wants=network-online.target
PartOf=koro-erp.target

[Service]
Type=simple
User=$SERVICE_USER
Group=$SERVICE_USER
WorkingDirectory=$INSTALL_DIR
EnvironmentFile=$INSTALL_DIR/etc/koro.env
Environment=SERVICE_NAME=${name}
Environment=SERVICE_PORT=${port}
ExecStart=$bin
Restart=on-failure
RestartSec=5
StandardOutput=append:$INSTALL_DIR/logs/${name}.log
StandardError=append:$INSTALL_DIR/logs/${name}.log
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=$INSTALL_DIR/data $INSTALL_DIR/logs

[Install]
WantedBy=koro-erp.target
EOF
  done

  # Umbrella target — start/stop everything with one command
  cat > /etc/systemd/system/koro-erp.target <<EOF
[Unit]
Description=Koro ERP — all services
Wants=$(for e in "${SERVICES[@]}"; do echo -n "koro-${e%%:*}.service "; done)

[Install]
WantedBy=multi-user.target
EOF

  systemctl daemon-reload
  systemctl enable koro-erp.target >/dev/null

  # Enable individual units so they auto-start on boot
  for entry in "${SERVICES[@]}"; do
    name="${entry%%:*}"
    [ -x "$INSTALL_DIR/bin/koro-${name}" ] || continue
    systemctl enable "koro-${name}.service" >/dev/null 2>&1 || true
  done

  ok "systemd units installed & enabled"
  info "Start everything now with:  sudo systemctl start koro-erp.target"
fi

# ── launchd (macOS) ──────────────────────────────────────────────
if [ "$OS" = "macos" ]; then
  info "Installing launchd agents under /Library/LaunchDaemons/…"
  for entry in "${SERVICES[@]}"; do
    name="${entry%%:*}"
    port="${entry##*:}"
    bin="$INSTALL_DIR/bin/koro-${name}"
    [ -x "$bin" ] || continue
    launcher="$INSTALL_DIR/bin/launch-koro-${name}.sh"
    cat > "$launcher" <<EOF
#!/usr/bin/env bash
set -a
source "$INSTALL_DIR/etc/koro.env"
set +a
export SERVICE_NAME="${name}"
export SERVICE_PORT="${port}"
exec "$bin"
EOF
    chmod +x "$launcher"
    plist="/Library/LaunchDaemons/com.koroerp.${name}.plist"
    cat > "$plist" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>Label</key><string>com.koroerp.${name}</string>
  <key>ProgramArguments</key><array><string>/bin/bash</string><string>$launcher</string></array>
  <key>WorkingDirectory</key><string>$INSTALL_DIR</string>
  <key>StandardOutPath</key><string>$INSTALL_DIR/logs/${name}.log</string>
  <key>StandardErrorPath</key><string>$INSTALL_DIR/logs/${name}.log</string>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
</dict></plist>
EOF
    launchctl bootstrap system "$plist" 2>/dev/null || true
  done
  ok "launchd agents installed"
fi

# ── Done ─────────────────────────────────────────────────────────
echo ""
echo -e "${BOLD}${GREEN}✔ Installation complete${NC}"
echo ""
echo "  Install dir : $INSTALL_DIR"
echo "  Config      : $INSTALL_DIR/etc/koro.env"
echo "  Logs        : $INSTALL_DIR/logs/"
echo "  Gateway URL : http://<this-host>:${GATEWAY_PORT}"
echo ""
if [ "$OS" = "linux" ]; then
  cat <<EOF
Manage the stack with systemd:
  sudo systemctl start   koro-erp.target      # start everything
  sudo systemctl stop    koro-erp.target      # stop everything
  sudo systemctl status  koro-auth.service    # one service
  sudo journalctl -fu    koro-gateway.service # tail gateway logs
EOF
fi
echo ""
echo "Next steps:"
echo "  1. Ensure PostgreSQL is reachable at ${DB_HOST}:${DB_PORT} and the 27 koro-erp-*"
echo "     databases exist (see https://koroworks.com/koroerp/binaries#databases)."
echo "  2. Open the Web UI and finish the Setup Wizard."
echo ""
