#!/usr/bin/env bash
# install.sh — instalador do Vulcan-Music Server (Core) para Linux.
# Baixa, instala e configura o servidor de musica na maquina do cliente (ex: Lenovo).
# Sobe a infra (Postgres, Redis, Meilisearch) via Docker e registra o servico (systemd).
#
# Uso:
#   curl -fsSL https://get.vulcanmusic.com/install.sh | bash
#   ou: ./install.sh
#
# Distribuicao DIRETA (nao vai para lojas). Ate termos certificados, este script
# vem com checksums GPG para o usuario verificar integridade (ver docs/SECURITY-WARNINGS.md).

set -euo pipefail

# ---- Configuracao ----
VM_VERSION="${VM_VERSION:-latest}"
VM_HOME="${VM_HOME:-/opt/vulcan-musik}"
VM_USER="${VM_USER:-vulcan}"
VM_PORT="${VM_PORT:-4533}"
# Hospedagem dos instalaveis: Cloudflare R2 (bucket publico vulcan-music-installers).
# 'latest/' eh espelhado pelo CI a cada release nova.
VM_RELEASE_BASE="${VM_RELEASE_BASE:-https://pub-8c12e933ae274e2d8176d39ee91fa8c3.r2.dev/${VM_VERSION}}"

# ---- AVISO DE SEGURANCA (NAO BLOQUEIA, so informa) ----
YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
cat <<BANNER

${YELLOW}╔════════════════════════════════════════════════════════════════════════╗
║                    AVISO DE SEGURANCA — LEIA                            ║
╠════════════════════════════════════════════════════════════════════════╣
║ Este instalador baixa o Vulcan-Music Server hospedado em R2 publico.    ║
║                                                                          ║
║ • Os binarios NAO sao assinados (sem certificado Apple/Windows).        ║
║ • Integridade verificada via SHA256 (incluso no download).              ║
║ • Codigo-fonte e proprietario; instalador eh open para auditoria.       ║
║ • Para parar a qualquer momento, pressione CTRL+C.                      ║
║                                                                          ║
║ Voce continua sob sua propria responsabilidade.                         ║
╚════════════════════════════════════════════════════════════════════════╝${NC}

BANNER
sleep 2

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BLUE='\033[0;34m'; NC='\033[0m'
info()  { echo -e "${GREEN}[vulcan-music]${NC} $*"; }
warn()  { echo -e "${YELLOW}[vulcan-music]${NC} $*"; }
err()   { echo -e "${RED}[vulcan-music]${NC} $*" >&2; }
step()  { echo -e "\n${BLUE}==>${NC} $*"; }

# ---- 0. Checagens ----
step "Verificando o sistema"
if [ "$(uname -s)" != "Linux" ]; then
  err "Este instalador e para Linux. Para Mac/Windows use o instalador apropriado."
  exit 1
fi

ARCH="$(uname -m)"
case "$ARCH" in
  x86_64)  VM_ARCH="amd64" ;;
  aarch64) VM_ARCH="arm64" ;;
  *) err "Arquitetura nao suportada: $ARCH"; exit 1 ;;
esac
info "Arquitetura: $VM_ARCH"

if [ "$(id -u)" -ne 0 ]; then
  warn "Recomendado rodar com sudo para instalar o servico systemd."
  warn "Tentando mesmo assim; algumas etapas podem pedir senha."
fi

# ---- 1. Dependencias do sistema ----
step "Verificando dependencias (Docker)"
if ! command -v docker >/dev/null 2>&1; then
  warn "Docker nao encontrado. Instalando via script oficial..."
  curl -fsSL https://get.docker.com | sh
  info "Docker instalado."
else
  info "Docker OK."
fi

if ! docker compose version >/dev/null 2>&1; then
  err "Docker Compose v2 nao disponivel. Atualize o Docker."
  exit 1
fi

# ---- 2. Usuario de servico ----
step "Configurando usuario de servico ($VM_USER)"
if ! id "$VM_USER" >/dev/null 2>&1; then
  useradd --system --create-home --shell /usr/sbin/nologin "$VM_USER" || \
    warn "Nao foi possivel criar usuario (pode ja existir ou faltar privilegio)."
fi

# ---- 3. Diretorios ----
step "Criando diretorios em $VM_HOME"
mkdir -p "$VM_HOME"/{bin,config,data,music}
info "Coloque sua musica em: $VM_HOME/music (ou aponte outra pasta no config)"

# ---- 4. Baixar o binario do Core ----
step "Baixando o Vulcan-Music Server ($VM_VERSION, $VM_ARCH)"
BINARY_URL="${VM_RELEASE_BASE}/vulcan-music-server-linux-${VM_ARCH}"
CHECKSUM_URL="${BINARY_URL}.sha256"

if curl -fsSL -o "$VM_HOME/bin/vulcan-music-server" "$BINARY_URL"; then
  info "Binario baixado."
  # Verificacao de integridade (ate termos assinatura de codigo)
  if curl -fsSL -o /tmp/vm.sha256 "$CHECKSUM_URL" 2>/dev/null; then
    EXPECTED="$(cat /tmp/vm.sha256 | awk '{print $1}')"
    ACTUAL="$(sha256sum "$VM_HOME/bin/vulcan-music-server" | awk '{print $1}')"
    if [ "$EXPECTED" = "$ACTUAL" ]; then
      info "Checksum verificado: integridade OK."
    else
      err "Checksum NAO confere. Abortando por seguranca."
      err "Esperado: $EXPECTED"
      err "Obtido:   $ACTUAL"
      exit 1
    fi
  else
    warn "Checksum nao disponivel; pulando verificacao (modo dev)."
  fi
  chmod +x "$VM_HOME/bin/vulcan-music-server"
else
  warn "Nao foi possivel baixar binario de release."
  warn "Em desenvolvimento, compile localmente: cd server && go build -o $VM_HOME/bin/vulcan-music-server ./cmd/server"
fi

# ---- 5. Infra (Postgres, Redis, Meilisearch) ----
step "Instalando a infraestrutura (Postgres, Redis, Meilisearch)"
cat > "$VM_HOME/docker-compose.yml" <<'COMPOSE'
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: vulcan
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: vulcan_music
    volumes:
      - ./data/pg:/var/lib/postgresql/data
    ports:
      - "127.0.0.1:5432:5432"
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - ./data/redis:/data
    ports:
      - "127.0.0.1:6379:6379"
  meilisearch:
    image: getmeili/meilisearch:v1.9
    restart: unless-stopped
    environment:
      MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
      MEILI_ENV: production
    volumes:
      - ./data/meili:/meili_data
    ports:
      - "127.0.0.1:7700:7700"
COMPOSE

# Gera senhas se nao existirem
if [ ! -f "$VM_HOME/config/secrets.env" ]; then
  info "Gerando segredos locais..."
  {
    echo "POSTGRES_PASSWORD=$(openssl rand -hex 24)"
    echo "MEILI_MASTER_KEY=$(openssl rand -hex 24)"
    echo "JWT_SECRET=$(openssl rand -hex 32)"
  } > "$VM_HOME/config/secrets.env"
  chmod 600 "$VM_HOME/config/secrets.env"
fi

( cd "$VM_HOME" && set -a && . config/secrets.env && set +a && docker compose up -d )
info "Infra no ar (apenas localhost, nao exposta para fora)."

# ---- 6. Config do servidor ----
step "Escrevendo configuracao do servidor"
if [ ! -f "$VM_HOME/config/config.toml" ]; then
  cat > "$VM_HOME/config/config.toml" <<CONFIG
# Vulcan-Music Server config
[server]
port = $VM_PORT
music_dir = "$VM_HOME/music"
data_dir = "$VM_HOME/data"

[database]
url = "postgres://vulcan@127.0.0.1:5432/vulcan_music"

[search]
meili_url = "http://127.0.0.1:7700"

[control_plane]
# URL do control plane central (Hetzner). O cliente registra este servidor la
# para permitir login/QR e relay. Deixe em branco para modo 100% local.
url = "https://musik.vulcanmusik.com"

[metadata]
# Chaves de APIs de metadados (preencha as que tiver). Sem elas, usa so as tags locais.
musicbrainz_enabled = true
lastfm_api_key = ""
discogs_token = ""
theaudiodb_key = ""
CONFIG
  info "Config criada em $VM_HOME/config/config.toml"
fi

chown -R "$VM_USER":"$VM_USER" "$VM_HOME" 2>/dev/null || true

# ---- 7. Servico systemd ----
step "Registrando servico systemd"
if command -v systemctl >/dev/null 2>&1; then
  cat > /etc/systemd/system/vulcan-music.service <<UNIT
[Unit]
Description=Vulcan-Music Server (Core)
After=network.target docker.service
Requires=docker.service

[Service]
Type=simple
User=$VM_USER
EnvironmentFile=$VM_HOME/config/secrets.env
ExecStart=$VM_HOME/bin/vulcan-music-server --config $VM_HOME/config/config.toml
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
UNIT
  systemctl daemon-reload
  systemctl enable vulcan-music.service
  systemctl start vulcan-music.service || warn "Servico nao iniciou (binario pode nao existir ainda em dev)."
  info "Servico registrado e habilitado no boot."
else
  warn "systemd nao encontrado; rode manualmente: $VM_HOME/bin/vulcan-music-server --config $VM_HOME/config/config.toml"
fi

# ---- 8. Final ----
step "Instalacao concluida"
IP="$(hostname -I 2>/dev/null | awk '{print $1}' || echo 'SEU_IP')"
echo ""
info "Vulcan-Music Server instalado em $VM_HOME"
info "Acesse o controle web em: http://$IP:$VM_PORT"
info "Coloque suas musicas em:   $VM_HOME/music"
echo ""
info "Para parear o celular: abra a interface acima, um QR code aparece,"
info "leia com a camera do celular e o controle web abre no navegador dele."
echo ""
warn "Primeira execucao: verifique o status com:  systemctl status vulcan-music"
