#!/usr/bin/env bash
# =============================================================================
# Jenkins 필수 플러그인 자동 설치
# 사용: sudo bash jenkins_plugins.sh [--jenkins-url URL] [--user USER] [--token TOKEN]
# =============================================================================
set -euo pipefail

JENKINS_URL="${JENKINS_URL:-http://localhost:8080}"
JENKINS_USER="${JENKINS_ADMIN_USER:-admin}"
JENKINS_TOKEN="${JENKINS_ADMIN_TOKEN:-}"
JENKINS_CLI_JAR="/tmp/jenkins-cli.jar"
LOG_FILE="/var/log/jenkins_plugins.log"

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
log()  { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $*" | tee -a "${LOG_FILE}"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*" | tee -a "${LOG_FILE}"; }
die()  { echo -e "${RED}[ERROR]${NC} $*" | tee -a "${LOG_FILE}"; exit 1; }

# ── 파라미터 파싱 ────────────────────────────────────────────────────────────
while [[ $# -gt 0 ]]; do
    case $1 in
        --jenkins-url) JENKINS_URL="$2"; shift 2 ;;
        --user)        JENKINS_USER="$2"; shift 2 ;;
        --token)       JENKINS_TOKEN="$2"; shift 2 ;;
        *) shift ;;
    esac
done

# ── Jenkins CLI 다운로드 ──────────────────────────────────────────────────────
download_cli() {
    log "Jenkins CLI 다운로드 중..."
    local retries=5
    for i in $(seq 1 $retries); do
        if curl -fsSL -o "${JENKINS_CLI_JAR}" \
            "${JENKINS_URL}/jnlpJars/jenkins-cli.jar" 2>/dev/null; then
            log "Jenkins CLI 다운로드 완료"
            return 0
        fi
        warn "CLI 다운로드 실패 (${i}/${retries}) — Jenkins가 기동 중인지 확인..."
        sleep 10
    done
    die "Jenkins CLI 다운로드 실패 — Jenkins가 실행 중인지 확인하세요."
}

# ── Jenkins CLI 실행 헬퍼 ────────────────────────────────────────────────────
jenkins_cli() {
    if [[ -n "${JENKINS_TOKEN}" ]]; then
        java -jar "${JENKINS_CLI_JAR}" \
            -s "${JENKINS_URL}" \
            -auth "${JENKINS_USER}:${JENKINS_TOKEN}" \
            "$@"
    else
        # 초기 비밀번호 사용
        local init_pw
        init_pw=$(cat /var/lib/jenkins/secrets/initialAdminPassword 2>/dev/null || echo "")
        java -jar "${JENKINS_CLI_JAR}" \
            -s "${JENKINS_URL}" \
            -auth "admin:${init_pw}" \
            "$@"
    fi
}

# ── 필수 플러그인 목록 ────────────────────────────────────────────────────────
PLUGINS=(
    # ── 파이프라인 핵심 ───────────────────────────────
    "workflow-aggregator"           # Pipeline (필수)
    "pipeline-stage-view"           # Pipeline Stage View
    "blueocean"                     # Blue Ocean UI
    "pipeline-graph-analysis"       # 파이프라인 그래프
    "pipeline-utility-steps"        # 유틸리티 스텝

    # ── 소스 관리 ────────────────────────────────────
    "git"                           # Git 플러그인
    "git-client"                    # Git Client
    "github"                        # GitHub 연동
    "gitlab-plugin"                 # GitLab 연동 (선택)
    "gitea"                         # Gitea 연동 (선택)

    # ── 빌드 도구 ────────────────────────────────────
    "maven-plugin"                  # Maven 지원
    "gradle"                        # Gradle 지원
    "nodejs"                        # Node.js 지원
    "ant"                           # Ant 지원

    # ── 자격증명 ─────────────────────────────────────
    "credentials"                   # Credentials Plugin
    "credentials-binding"           # withCredentials()
    "ssh-credentials"               # SSH 자격증명
    "plain-credentials"             # Secret Text
    "ssh-agent"                     # SSH Agent

    # ── 배포 / 원격 실행 ──────────────────────────────
    "publish-over-ssh"              # SCP/SSH 배포
    "ssh-steps"                     # SSH Steps
    "copy-artifact"                 # 아티팩트 복사
    "artifact-manager-s3"           # S3 아티팩트 (선택)

    # ── 테스트 & 품질 ─────────────────────────────────
    "junit"                         # JUnit 결과
    "jacoco"                        # 코드 커버리지
    "sonar"                         # SonarQube 연동
    "htmlpublisher"                 # HTML 보고서

    # ── 알림 ─────────────────────────────────────────
    "email-ext"                     # 이메일 알림
    "mailer"                        # 기본 메일

    # ── 보안 ─────────────────────────────────────────
    "role-strategy"                 # RBAC
    "mask-passwords"                # 비밀번호 마스킹
    "audit-trail"                   # 감사 로그
    "matrix-auth"                   # Matrix Authorization

    # ── Gitea 연동 (웹훅 트리거) ─────────────────────────
    "generic-webhook-trigger"       # Gitea Push/PR 웹훅 수신
    "gitea"                         # Gitea 전용 SCM 플러그인

    # ── 설정 관리 ─────────────────────────────────────
    "configuration-as-code"         # JCasC
    "configuration-as-code-support" # JCasC 지원

    # ── UI & 유틸리티 ─────────────────────────────────
    "timestamper"                   # 타임스탬프
    "build-timeout"                 # 빌드 타임아웃
    "ws-cleanup"                    # 워크스페이스 정리
    "ansicolor"                     # ANSI 컬러 출력
    "parameterized-trigger"         # 파라미터 트리거
    "rebuild"                       # 재빌드 버튼
    "build-discarder"               # 빌드 보관 정책
)

# ── 플러그인 설치 ─────────────────────────────────────────────────────────────
install_plugins() {
    log "총 ${#PLUGINS[@]}개 플러그인 설치 시작..."

    local failed=()
    for plugin in "${PLUGINS[@]}"; do
        log "  설치 중: ${plugin}"
        if jenkins_cli install-plugin "${plugin}" -restart 2>/dev/null; then
            : # 성공
        else
            # restart 없이 재시도
            if jenkins_cli install-plugin "${plugin}" 2>/dev/null; then
                : # 성공
            else
                warn "  설치 실패: ${plugin}"
                failed+=("${plugin}")
            fi
        fi
    done

    if [[ ${#failed[@]} -gt 0 ]]; then
        warn "설치 실패 플러그인 (${#failed[@]}개):"
        for p in "${failed[@]}"; do
            warn "  - ${p}"
        done
    fi

    log "플러그인 설치 완료 — Jenkins 재시작 중..."
}

# ── Jenkins 재시작 대기 ───────────────────────────────────────────────────────
wait_for_jenkins() {
    log "Jenkins 재시작 대기 중..."
    jenkins_cli safe-restart 2>/dev/null || systemctl restart jenkins

    local retries=30
    for i in $(seq 1 $retries); do
        if curl -fsSL -o /dev/null "${JENKINS_URL}/login" 2>/dev/null; then
            log "Jenkins 준비 완료"
            return 0
        fi
        echo -n "."
        sleep 5
    done
    warn "Jenkins 재시작 확인 타임아웃 — 수동으로 확인하세요."
}

# ── 메인 ─────────────────────────────────────────────────────────────────────
main() {
    log "=== Jenkins 플러그인 설치 시작 ==="
    download_cli
    install_plugins
    wait_for_jenkins
    log "=== Jenkins 플러그인 설치 완료 ==="
    echo ""
    echo -e "${GREEN}플러그인 설치 완료!${NC}"
    echo "Jenkins: ${JENKINS_URL}"
    echo "로그:    ${LOG_FILE}"
}

main "$@"
