#!/usr/bin/env bash
# =============================================================================
# Jenkins 자동 설치 스크립트
# 대상: RHEL 8/9, Rocky Linux 8/9, Ubuntu 20.04/22.04
# 사용: sudo bash jenkins_install.sh
# =============================================================================
set -euo pipefail

JENKINS_PORT="${JENKINS_PORT:-8080}"
JAVA_VERSION="${JAVA_VERSION:-17}"
LOG_FILE="/var/log/jenkins_install.log"

# ── 색상 출력 ─────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; 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; }

# ── 루트 권한 확인 ───────────────────────────────────────────────────────────
[[ $EUID -ne 0 ]] && die "root 권한으로 실행하세요: sudo bash $0"

# ── OS 감지 ──────────────────────────────────────────────────────────────────
detect_os() {
    if [[ -f /etc/os-release ]]; then
        source /etc/os-release
        OS_ID="${ID}"
        OS_VERSION_ID="${VERSION_ID%%.*}"
    else
        die "OS를 감지할 수 없습니다."
    fi
    log "OS 감지: ${ID} ${VERSION_ID}"
}

# ── Java 설치 ────────────────────────────────────────────────────────────────
install_java() {
    log "Java ${JAVA_VERSION} 설치 중..."
    case "${OS_ID}" in
        rhel|rocky|centos|almalinux)
            dnf install -y "java-${JAVA_VERSION}-openjdk-devel" || \
            dnf install -y "java-${JAVA_VERSION}-amazon-corretto-devel" || \
            die "Java ${JAVA_VERSION} 설치 실패"
            ;;
        ubuntu|debian)
            apt-get update -qq
            apt-get install -y "openjdk-${JAVA_VERSION}-jdk" || \
            die "Java ${JAVA_VERSION} 설치 실패"
            ;;
        *) die "지원하지 않는 OS: ${OS_ID}" ;;
    esac
    java -version
    log "Java 설치 완료"
}

# ── Jenkins 저장소 등록 ────────────────────────────────────────────────────────
add_jenkins_repo() {
    log "Jenkins 저장소 등록 중..."
    case "${OS_ID}" in
        rhel|rocky|centos|almalinux)
            wget -q -O /etc/yum.repos.d/jenkins.repo \
                https://pkg.jenkins.io/redhat-stable/jenkins.repo
            rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
            dnf upgrade -y
            ;;
        ubuntu|debian)
            apt-get install -y curl gnupg
            curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | \
                tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
            echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
                https://pkg.jenkins.io/debian-stable binary/" | \
                tee /etc/apt/sources.list.d/jenkins.list > /dev/null
            apt-get update -qq
            ;;
    esac
    log "저장소 등록 완료"
}

# ── Jenkins 설치 ─────────────────────────────────────────────────────────────
install_jenkins() {
    log "Jenkins LTS 설치 중..."
    case "${OS_ID}" in
        rhel|rocky|centos|almalinux)
            dnf install -y jenkins
            ;;
        ubuntu|debian)
            apt-get install -y jenkins
            ;;
    esac

    # 포트 변경 (기본값 8080이 아닌 경우)
    if [[ "${JENKINS_PORT}" != "8080" ]]; then
        log "Jenkins 포트 변경: 8080 → ${JENKINS_PORT}"
        case "${OS_ID}" in
            rhel|rocky|centos|almalinux)
                sed -i "s/^HTTP_PORT=.*/HTTP_PORT=${JENKINS_PORT}/" \
                    /etc/sysconfig/jenkins 2>/dev/null || \
                    echo "HTTP_PORT=${JENKINS_PORT}" >> /etc/sysconfig/jenkins
                ;;
            ubuntu|debian)
                sed -i "s/^HTTP_PORT=.*/HTTP_PORT=${JENKINS_PORT}/" \
                    /etc/default/jenkins 2>/dev/null || \
                    echo "HTTP_PORT=${JENKINS_PORT}" >> /etc/default/jenkins
                ;;
        esac
    fi

    systemctl enable jenkins
    systemctl start jenkins
    log "Jenkins 시작 완료"
}

# ── 방화벽 설정 ────────────────────────────────────────────────────────────────
configure_firewall() {
    log "방화벽 포트 ${JENKINS_PORT} 개방..."
    if command -v firewall-cmd &>/dev/null && systemctl is-active firewalld &>/dev/null; then
        firewall-cmd --permanent --add-port="${JENKINS_PORT}/tcp"
        firewall-cmd --reload
        log "firewalld: 포트 ${JENKINS_PORT} 개방"
    elif command -v ufw &>/dev/null; then
        ufw allow "${JENKINS_PORT}/tcp"
        log "ufw: 포트 ${JENKINS_PORT} 개방"
    else
        warn "방화벽 관리 도구를 찾을 수 없습니다. 수동으로 포트를 개방하세요."
    fi
}

# ── SELinux 설정 (RHEL 계열) ──────────────────────────────────────────────────
configure_selinux() {
    if command -v getenforce &>/dev/null && [[ "$(getenforce)" != "Disabled" ]]; then
        log "SELinux 설정 중..."
        setsebool -P httpd_can_network_connect 1 2>/dev/null || true
        semanage port -a -t http_port_t -p tcp "${JENKINS_PORT}" 2>/dev/null || \
        semanage port -m -t http_port_t -p tcp "${JENKINS_PORT}" 2>/dev/null || \
        warn "SELinux 포트 설정 실패 — 수동 설정이 필요할 수 있습니다."
        log "SELinux 설정 완료"
    fi
}

# ── 초기 설정 디렉터리 준비 ────────────────────────────────────────────────────
prepare_directories() {
    log "디렉터리 구조 준비..."
    mkdir -p /var/lib/jenkins/casc_configs
    mkdir -p /backup/jenkins
    chown -R jenkins:jenkins /var/lib/jenkins/casc_configs
    chown -R jenkins:jenkins /backup/jenkins 2>/dev/null || true
    log "디렉터리 준비 완료"
}

# ── 완료 메시지 ───────────────────────────────────────────────────────────────
print_summary() {
    local admin_pw
    admin_pw=$(cat /var/lib/jenkins/secrets/initialAdminPassword 2>/dev/null || echo "N/A")
    local server_ip
    server_ip=$(hostname -I | awk '{print $1}')

    echo ""
    echo -e "${GREEN}╔══════════════════════════════════════════════════╗${NC}"
    echo -e "${GREEN}║         Jenkins 설치 완료                         ║${NC}"
    echo -e "${GREEN}╠══════════════════════════════════════════════════╣${NC}"
    echo -e "${GREEN}║${NC} URL:     http://${server_ip}:${JENKINS_PORT}                   "
    echo -e "${GREEN}║${NC} 초기 PW: ${admin_pw}           "
    echo -e "${GREEN}║${NC}                                                   "
    echo -e "${GREEN}║${NC} 다음 단계:                                         "
    echo -e "${GREEN}║${NC}  1. 브라우저에서 URL 접속                           "
    echo -e "${GREEN}║${NC}  2. 초기 비밀번호 입력                              "
    echo -e "${GREEN}║${NC}  3. 플러그인 설치: sudo bash jenkins_plugins.sh     "
    echo -e "${GREEN}╚══════════════════════════════════════════════════╝${NC}"
    echo ""
    log "설치 로그: ${LOG_FILE}"
}

# ── 메인 실행 ────────────────────────────────────────────────────────────────
configure_gitea_webhook() {
    log "=== Gitea 웹훅 자동 등록 ==="
    local script_dir
    script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    local webhook_script="${script_dir}/../notify/gitea_webhook.sh"

    if [[ -f "$webhook_script" ]]; then
        # Gitea가 기동 중이면 웹훅 자동 등록
        if curl -sf "${GITEA_BASE_URL:-http://localhost:3000}/api/v1/version" -o /dev/null 2>/dev/null; then
            JENKINS_URL="${JENKINS_URL:-http://localhost:${JENKINS_PORT}}" \
            bash "$webhook_script" \
              && log "Gitea 웹훅 등록 완료" \
              || warn "Gitea 웹훅 등록 실패 — 나중에 수동 실행: bash $webhook_script"
        else
            warn "Gitea 서비스 없음 — 웹훅 등록 건너뜀"
            warn "Gitea 시작 후 실행: bash $webhook_script"
        fi
    else
        warn "webhook 스크립트 없음: $webhook_script"
    fi
}

main() {
    log "=== Jenkins 설치 시작 ==="
    detect_os
    install_java
    add_jenkins_repo
    install_jenkins
    configure_firewall
    configure_selinux
    prepare_directories
    configure_gitea_webhook
    print_summary
    log "=== Jenkins 설치 완료 ==="
}

main "$@"
