pipeline {
    // 에이전트 설정 (Mac 머신 사용)
    agent { label 'mac' }

    // SCM Polling 트리거 설정 (금요일마다 5분마다 체크)
    triggers {
        pollSCM('H/5 * * * 5')  // "매주 금요일 5분마다 SCM 변경 체크"
    }

    // 파라미터 정의
    parameters {
        string(name: 'PRJ_URL', defaultValue: '<https://github.com/Geekble-Game/SerpentOfTheEnd-client.git>', description: 'GitHub repository URL')  // Git URL
        string(name: 'BRANCH', defaultValue: 'develop', description: 'Branch to build')  // 브랜치명
        string(name: 'UNITY_VER', defaultValue: '6000.0.26f1', description: 'Unity Editor version')  // 유니티 버전
        string(name: 'BUILD_ROOT', defaultValue: '/Users/msg/Desktop/build', description: 'Build output root directory')  // 빌드 결과 저장 경로
        booleanParam(name: 'UNITY_BUILD_AAB', defaultValue: true, description: 'Build Android App Bundle (AAB)')  // AAB 여부
    }

    // 환경 변수 설정
    environment {
        UNITY_PATH = "/Applications/Unity/Hub/Editor/${params.UNITY_VER}/Unity.app/Contents/MacOS/Unity"
    }

    // 빌드 옵션
    options {
        disableConcurrentBuilds()  // 중복 빌드 방지
    }

    // 빌드 단계 (Stages)
    stages {

        // 1단계: Clean Workspace
        stage('Clean Workspace') {
            steps {
                cleanWs()
            }
        }

        // 2단계: Git Checkout (서브모듈 포함)
        stage('Checkout with Submodules') {
            steps {
                checkout([
                    $class: 'GitSCM',
                    branches: [[name: "*/${params.BRANCH}"]],
                    userRemoteConfigs: [[
                        url: "${params.PRJ_URL}",
                        credentialsId: 'SerpentOfTheEnd_Jenkins_Polling_TOKEN'
                    ]],
                    extensions: [
                        [$class: 'SubmoduleOption', recursiveSubmodules: true, trackingSubmodules: true],
                        [$class: 'RelativeTargetDirectory', relativeTargetDir: 'SerpentOfTheEnd-client']
                    ]
                ])
            }
        }

        // 3단계: 프로젝트명 초기화
        stage('Init Project Name') {
            steps {
                script {
                    def (repoName, projectName) = parseProjectInfoFromRepoUrl(params.PRJ_URL)

                    env.BUILD_REPO_NAME = repoName
                    env.BUILD_PROJECT_NAME = projectName

                    echo "[INFO] Git URL: ${params.PRJ_URL}"
                    echo "[INFO] REPO Name: ${env.BUILD_REPO_NAME}"
                    echo "[INFO] Project Name: ${env.BUILD_PROJECT_NAME}"
                    echo "[INFO] Branch Name: ${params.BRANCH}"
                }
            }
        }

        // 4단계: 유니티 버전 확인
        stage('Unity Version Check') {
            steps {
                sh """
                    "${env.UNITY_PATH}" -version
                """
            }
        }

        // 5단계: Unity Android 빌드
        stage('Build Unity Android') {
            options {
                timeout(time: 1, unit: 'HOURS')  // 1시간 제한
            }
            steps {
                withCredentials([
                    string(credentialsId: 'keystore_pass', variable: 'KEYSTORE_PASS'),
                    string(credentialsId: 'key_alias', variable: 'KEY_ALIAS'),
                    string(credentialsId: 'key_alias_pass', variable: 'KEY_ALIAS_PASS')
                ]) {
                    script {
                        env.BUILD_VERSION = getUnityVersionCode()  // bundleVersion 추출
                        env.BUILD_NAME = getBuildName(env.BUILD_VERSION)  // 빌드명 생성
                        env.DEFAULT_BUILD_PATH = "${env.BUILD_PROJECT_NAME}/${params.BRANCH}/${env.BUILD_VERSION}"  // 빌드 경로

                        // 출력/로그 경로 설정
                        def localBuildPath = "${params.BUILD_ROOT}/${env.DEFAULT_BUILD_PATH}"
                        def outputDir = "${localBuildPath}/Builds/android"
                        def logDir = "${localBuildPath}/Logs"

                        def logPath = "${logDir}/${env.BUILD_NAME}.log"
                        def ext = (params.UNITY_BUILD_AAB) ? 'aab' : 'apk'
                        def filePath = "${outputDir}/${env.BUILD_NAME}.${ext}"

                        def projectPath = "${env.WORKSPACE}/${env.BUILD_REPO_NAME}/${env.BUILD_PROJECT_NAME}"
                        def keystorePath = "${projectPath}.keystore"

                        // 환경 변수 export
                        env.BUILD_OUTPUT_PATH = filePath
                        env.BUILD_LOG_PATH = logPath

                        withEnv([
                            "UNITY_BUILD_PATH=${filePath}",
                            "UNITY_BUILD_AAB=${params.UNITY_BUILD_AAB}",
                            "KEYSTORE_PATH=${keystorePath}",
                            "KEYSTORE_PASS=${env.KEYSTORE_PASS}",
                            "KEY_ALIAS=${env.KEY_ALIAS}",
                            "KEY_ALIAS_PASS=${env.KEY_ALIAS_PASS}"
                        ]) {
                            // 빌드 실행
                            sh """
                                mkdir -p "${logDir}"

                                "${env.UNITY_PATH}" \
                                  -batchmode \
                                  -nographics \
                                  -projectPath "${projectPath}" \
                                  -executeMethod AndroidBuilder.BuildAndroid \
                                  -quit \
                                  -logFile "${logPath}" \
                                  -buildTarget android
                            """
                        }

                        // 빌드 결과 확인
                        if (!fileExists(filePath)) {
                            error "[ERROR] Build failed: ${filePath} not found"
                        }
                    }
                }
            }
        }

        // 6단계: S3 업로드
        stage('Upload to S3') {
            steps {
                withCredentials([
                    [$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'AWS_CREDENTIALS']
                ]) {
                    script {
                        env.BUILD_S3_URL = uploadToS3(env.BUILD_OUTPUT_PATH, env.DEFAULT_BUILD_PATH)
                    }
                }
            }
        }
    }

    // Post 빌드 작업 (성공 / 실패)
    post {
        // 성공 시
        success {
            withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'AWS_CREDENTIALS']]) {
                script {
                    sendSlack("success", "#36a64f")  // Slack 성공 메시지
                }
            }
        }
        // 실패 시
        failure {
            withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'AWS_CREDENTIALS']]) {
                script {
                    env.BUILD_FAIL_LOG_URL = uploadToS3(env.BUILD_LOG_PATH, "${env.DEFAULT_BUILD_PATH}/logs")  // 실패 로그 업로드
                    sendSlack("failure", "#FF0000")  // Slack 실패 메시지
                }
            }
        }
    }
}

//
// 유틸 함수들
//

// Git URL → repoName, projectName 추출
def parseProjectInfoFromRepoUrl(repoUrl) {
    def repoName = repoUrl.tokenize('/').last().replace('.git', '')
    def projectName = repoName.replaceFirst(/-client$/, '')
    return [repoName, projectName]
}

// bundleVersion 추출
def getUnityVersionCode() {
    def versionFile = "${env.WORKSPACE}/${env.BUILD_REPO_NAME}/${env.BUILD_PROJECT_NAME}/ProjectSettings/ProjectSettings.asset"

    if (!fileExists(versionFile)) {
        error "[ERROR] ProjectSettings.asset not found: ${versionFile}"
    }

    def versionName = sh(
        script: """
            grep 'bundleVersion:' "${versionFile}" \\
            | head -n 1 \\
            | sed 's/.*:[ ]*//'
        """,
        returnStdout: true
    ).trim()

    if (!versionName) {
        error "[ERROR] bundleVersion not found in ${versionFile}"
    }

    echo "[INFO] Extracted VERSION_NAME: ${versionName}"

    return "${versionName}"
}

// 빌드명 생성
def getBuildName(version) {
    return "SE_${version}"
}

// S3 업로드
def uploadToS3(filePath, uploadPath, region = 'ap-northeast-2') {
    def bucketName = "msg-game"
    def s3Path = "s3://${bucketName}/${uploadPath}/android/"
    def fileName = filePath.tokenize('/')[-1]
    def s3Url = "<https://$>{bucketName}.s3.${region}.amazonaws.com/${uploadPath}/android/${fileName}"

    sh """
        export PATH=/usr/local/bin:/opt/homebrew/bin:\$PATH
        aws s3 cp "${filePath}" "${s3Path}" --region ${region}
    """

    echo "[INFO] Uploaded to S3: ${s3Url}"

    return s3Url
}

// Slack 메시지 전송
def sendSlack(String status, String color) {
    def title = (status == "success") ? "✅ *Unity Android 빌드 성공*" : "❌ *Unity Android 빌드 실패*"

    def downloadUrl = (status == "success") ? env.BUILD_S3_URL : env.BUILD_FAIL_LOG_URL

    def curlBody = """{
        "text": "${title}",
        "attachments": [{
            "color": "${color}",
            "fields": [
                {"title": "Project", "value": "${env.BUILD_PROJECT_NAME}", "short": true},
                {"title": "Branch", "value": "${params.BRANCH}", "short": true},
                {"title": "Job", "value": "${env.JOB_NAME} #${env.BUILD_NUMBER}", "short": true},
                {"title": "Download", "value": "${downloadUrl}", "short": false}
            ]
        }]
    }"""

    withCredentials([string(credentialsId: 'SLACK_WEBHOOK_URL', variable: 'SLACK_URL')]) {
        sh """
            curl -X POST -H 'Content-type: application/json' --data '${curlBody}' "$SLACK_URL"
        """
    }
}