#!/bin/bash
# =============================================================================
# sync-nexus.sh - 로컬 Maven 의존성을 Nexus에 동기화
#
# 사용법:
#   ./scripts/sync-nexus.sh              # 실제 업로드
#   ./scripts/sync-nexus.sh --dry-run    # 업로드 대상만 확인
# =============================================================================

set -eo pipefail

# --- SDKMAN 초기화 (set -u 전에 실행) ---
if [ -f "$HOME/.sdkman/bin/sdkman-init.sh" ]; then
    source "$HOME/.sdkman/bin/sdkman-init.sh" 2>/dev/null || true
fi

# --- 설정 ---
NEXUS_URL="http://10.26.252.39:8081"
REPO_ID="mda-backend-repository"
NEXUS_USER="admin"
NEXUS_PASS="8932"
LOCAL_REPO="$HOME/.m2/repository"

# --- 옵션 파싱 ---
DRY_RUN=false
if [[ "${1:-}" == "--dry-run" ]]; then
    DRY_RUN=true
    echo "=== DRY RUN 모드 (업로드하지 않음) ==="
fi

# --- 카운터 ---
TOTAL=0
SKIPPED=0
UPLOADED=0
FAILED=0

# Nexus에 아티팩트 존재 여부 확인 (HTTP HEAD로 .pom 파일 체크)
check_exists() {
    local group_path=$1
    local artifact_id=$2
    local version=$3
    local pom_url="${NEXUS_URL}/repository/${REPO_ID}/${group_path}/${artifact_id}/${version}/${artifact_id}-${version}.pom"
    local http_code
    http_code=$(curl -s -o /dev/null -w "%{http_code}" -u "${NEXUS_USER}:${NEXUS_PASS}" --connect-timeout 5 "$pom_url" < /dev/null)
    [[ "$http_code" == "200" ]]
}

# 파일 업로드 (HTTP PUT)
upload_file() {
    local file_path=$1
    local remote_path=$2
    local url="${NEXUS_URL}/repository/${REPO_ID}/${remote_path}"

    if [ ! -f "$file_path" ]; then
        return 1
    fi

    local http_code
    http_code=$(curl -s -o /dev/null -w "%{http_code}" -u "${NEXUS_USER}:${NEXUS_PASS}" --upload-file "$file_path" --connect-timeout 10 --max-time 120 "$url" < /dev/null)
    [[ "$http_code" == "201" || "$http_code" == "200" ]]
}

# 아티팩트 업로드 (pom + jar + 기타)
upload_artifact() {
    local group_id=$1
    local artifact_id=$2
    local version=$3
    local packaging=$4

    local group_path
    group_path=$(echo "$group_id" | tr '.' '/')
    local base_dir="${LOCAL_REPO}/${group_path}/${artifact_id}/${version}"
    local base_name="${artifact_id}-${version}"
    local remote_base="${group_path}/${artifact_id}/${version}"

    local success=true

    # POM 업로드 (필수)
    local pom_file="${base_dir}/${base_name}.pom"
    if [ -f "$pom_file" ]; then
        if upload_file "$pom_file" "${remote_base}/${base_name}.pom"; then
            :
        else
            echo "    [FAIL] POM 업로드 실패"
            success=false
        fi
    fi

    # JAR 업로드 (pom 패키징이 아닌 경우)
    if [[ "$packaging" != "pom" ]]; then
        local jar_file="${base_dir}/${base_name}.${packaging}"
        if [ -f "$jar_file" ]; then
            if upload_file "$jar_file" "${remote_base}/${base_name}.${packaging}"; then
                :
            else
                echo "    [FAIL] ${packaging} 업로드 실패"
                success=false
            fi
        fi
    fi

    $success
}

echo ""
echo "=== Nexus 동기화 시작 ==="
echo "  Nexus: ${NEXUS_URL}/repository/${REPO_ID}"
echo "  로컬:  ${LOCAL_REPO}"
echo ""

# Nexus 연결 확인
if ! curl -s -o /dev/null -w "" -u "${NEXUS_USER}:${NEXUS_PASS}" --connect-timeout 5 "${NEXUS_URL}/service/rest/v1/repositories" 2>/dev/null; then
    echo "[ERROR] Nexus(${NEXUS_URL})에 연결할 수 없습니다."
    exit 1
fi
echo "[OK] Nexus 연결 확인"
echo ""

# Maven dependency:list로 GAV 목록 추출
echo "의존성 목록 추출 중..."
DEP_LIST=$(mvn dependency:list -DoutputAbsoluteArtifactFilename=true 2>/dev/null | grep "^\[INFO\]    " | sed 's/\[INFO\]    //' | sed 's/ -- .*//')

echo ""
echo "--- 동기화 진행 ---"

while IFS= read -r line; do
    # 형식: groupId:artifactId:packaging:version:scope:/path/to/file
    IFS=':' read -r group_id artifact_id packaging version scope rest <<< "$line"

    if [[ -z "$group_id" || -z "$artifact_id" || -z "$version" ]]; then
        continue
    fi

    TOTAL=$((TOTAL + 1))
    local_group_path=$(echo "$group_id" | tr '.' '/')

    # Nexus 존재 여부 확인
    if check_exists "$local_group_path" "$artifact_id" "$version"; then
        SKIPPED=$((SKIPPED + 1))
        continue
    fi

    # 신규 아티팩트 발견
    echo "[NEW] ${group_id}:${artifact_id}:${version} (${packaging})"

    if $DRY_RUN; then
        UPLOADED=$((UPLOADED + 1))
    else
        if upload_artifact "$group_id" "$artifact_id" "$version" "$packaging"; then
            echo "  -> 업로드 완료"
            UPLOADED=$((UPLOADED + 1))
        else
            echo "  -> 업로드 실패"
            FAILED=$((FAILED + 1))
        fi
    fi

done <<< "$DEP_LIST"

echo ""
echo "=== 동기화 완료 ==="
echo "  전체: ${TOTAL}"
echo "  스킵 (이미 존재): ${SKIPPED}"
if $DRY_RUN; then
    echo "  업로드 대상: ${UPLOADED}"
else
    echo "  업로드 성공: ${UPLOADED}"
    echo "  업로드 실패: ${FAILED}"
fi
echo ""
