#!/usr/bin/env bash
# =============================================================
# SonarQube Community Edition — 一鍵安裝腳本
# 使用方式：sudo bash /var/www/html/portal/scripts/setup-sonarqube.sh
# =============================================================
set -euo pipefail

SONAR_PORT=9000
SONAR_CONTAINER=sonarqube
SONAR_DATA=/var/lib/sonarqube
SONAR_IMAGE=sonarqube:community
ENV_FILE=/var/www/html/portal/.env
ADMIN_NEW_PASS="Steps@sonar2026"   # 首次登入後自動改密碼

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
info()  { echo -e "${GREEN}[✓]${NC} $*"; }
warn()  { echo -e "${YELLOW}[!]${NC} $*"; }
error() { echo -e "${RED}[✗]${NC} $*"; exit 1; }

# ── 0. 確認 root ─────────────────────────────────────────────
[[ $EUID -ne 0 ]] && error "請以 sudo 執行：sudo bash $0"

# ── 1. sysctl 設定（Elasticsearch 必要）──────────────────────
info "設定 vm.max_map_count=524288..."
sysctl -w vm.max_map_count=524288
sysctl -w fs.file-max=131072
grep -q 'vm.max_map_count' /etc/sysctl.conf || echo 'vm.max_map_count=524288' >> /etc/sysctl.conf
grep -q 'fs.file-max'      /etc/sysctl.conf || echo 'fs.file-max=131072'      >> /etc/sysctl.conf

# ── 2. 建立資料目錄 ──────────────────────────────────────────
info "建立 SonarQube 資料目錄..."
mkdir -p ${SONAR_DATA}/{data,extensions,logs,temp}
# 9000 是 SonarQube 執行的 UID（容器內）
chown -R 1000:1000 ${SONAR_DATA}
chmod -R 755 ${SONAR_DATA}

# ── 3. 停止舊容器（若存在）──────────────────────────────────
if docker ps -a --format '{{.Names}}' | grep -q "^${SONAR_CONTAINER}$"; then
    warn "發現舊容器 ${SONAR_CONTAINER}，停止並移除..."
    docker stop ${SONAR_CONTAINER} 2>/dev/null || true
    docker rm   ${SONAR_CONTAINER} 2>/dev/null || true
fi

# ── 4. 拉取映像 ──────────────────────────────────────────────
info "下載 ${SONAR_IMAGE}（首次可能需要幾分鐘）..."
docker pull ${SONAR_IMAGE}

# ── 5. 啟動容器 ──────────────────────────────────────────────
info "啟動 SonarQube..."
docker run -d \
    --name ${SONAR_CONTAINER} \
    --restart unless-stopped \
    -p ${SONAR_PORT}:9000 \
    -v ${SONAR_DATA}/data:       /opt/sonarqube/data \
    -v ${SONAR_DATA}/extensions: /opt/sonarqube/extensions \
    -v ${SONAR_DATA}/logs:       /opt/sonarqube/logs \
    -v ${SONAR_DATA}/temp:       /opt/sonarqube/temp \
    -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true \
    ${SONAR_IMAGE}

# ── 6. 等待 SonarQube 啟動 ──────────────────────────────────
info "等待 SonarQube 啟動（最長 3 分鐘）..."
WAIT=0
until curl -sf "http://localhost:${SONAR_PORT}/api/system/status" \
       | grep -q '"status":"UP"'; do
    sleep 5; WAIT=$((WAIT+5))
    echo -n "."
    [[ $WAIT -ge 180 ]] && { echo; error "SonarQube 啟動逾時，請執行：docker logs ${SONAR_CONTAINER}"; }
done
echo
info "SonarQube 已啟動！"

# ── 7. 修改 admin 密碼 ───────────────────────────────────────
info "修改 admin 預設密碼..."
HTTP=$(curl -s -o /dev/null -w "%{http_code}" \
    -u admin:admin \
    -X POST "http://localhost:${SONAR_PORT}/api/users/change_password" \
    -d "login=admin&previousPassword=admin&password=${ADMIN_NEW_PASS}")
if [[ "$HTTP" == "204" ]]; then
    info "密碼已更改為：${ADMIN_NEW_PASS}"
else
    warn "密碼修改失敗（HTTP ${HTTP}），可能已改過，嘗試用新密碼繼續..."
fi

# ── 8. 建立 API Token ────────────────────────────────────────
info "建立 API Token..."
# 先嘗試新密碼，失敗則用 admin/admin
for PASS in "${ADMIN_NEW_PASS}" "admin"; do
    TOKEN_RESP=$(curl -s -u "admin:${PASS}" \
        -X POST "http://localhost:${SONAR_PORT}/api/user_tokens/generate" \
        -d "name=portal-token-$(date +%s)")
    TOKEN=$(echo "${TOKEN_RESP}" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('token',''))" 2>/dev/null || true)
    [[ -n "$TOKEN" ]] && break
done

if [[ -z "$TOKEN" ]]; then
    warn "自動建立 Token 失敗，請手動登入 http://localhost:${SONAR_PORT} 建立 Token"
    warn "帳號：admin  密碼：${ADMIN_NEW_PASS}"
    TOKEN="請手動填入"
fi

# ── 9. 更新 .env ─────────────────────────────────────────────
info "更新 ${ENV_FILE}..."
# 移除舊有 SONAR 設定
grep -v -E '^SONAR_' "${ENV_FILE}" > /tmp/.env.tmp || true
# 加入新設定
cat >> /tmp/.env.tmp <<EOF

# SonarQube
SONAR_URL=http://localhost:${SONAR_PORT}
SONAR_TOKEN=${TOKEN}
EOF
cp /tmp/.env.tmp "${ENV_FILE}"
chown www-data:www-data "${ENV_FILE}" 2>/dev/null || true
rm /tmp/.env.tmp

# ── 10. 清除 Laravel cache ───────────────────────────────────
info "清除 Laravel config cache..."
php /var/www/html/portal/artisan config:clear 2>/dev/null || true

# ── 完成 ──────────────────────────────────────────────────────
echo
echo -e "${GREEN}══════════════════════════════════════════${NC}"
echo -e "${GREEN}  SonarQube 安裝完成！${NC}"
echo -e "${GREEN}══════════════════════════════════════════${NC}"
echo
echo "  Web UI：  http://localhost:${SONAR_PORT}"
echo "  帳號：    admin"
echo "  密碼：    ${ADMIN_NEW_PASS}"
echo "  Token：   ${TOKEN}"
echo
echo "  容器管理："
echo "    查看 log：docker logs -f ${SONAR_CONTAINER}"
echo "    停止：    docker stop ${SONAR_CONTAINER}"
echo "    啟動：    docker start ${SONAR_CONTAINER}"
echo
info "portal .env 已自動更新，可直接使用源碼掃描 → SonarQube 功能"
