import groovy.json.JsonSlurper

def getTeamFromCodeowners(String projectBaseDir) {
    def possiblePaths = ["${projectBaseDir}/CODEOWNERS", "${projectBaseDir}/.github/CODEOWNERS"]
    def codeownersFileContent = null

    for (path in possiblePaths) {
        if (fileExists(path)) {
            echo "Found CODEOWNERS file at: ${path}"
            codeownersFileContent = readFile(path)
            break
        }
    }

    if (codeownersFileContent == null) {
        echo "CODEOWNERS file not found in root or .github/. Skipping project tag."
        return null
    }

    def defaultTeam = null
    def firstTeam = null

    codeownersFileContent.readLines().each { line ->
        line = line.trim()
        // skip comments & empty lines
        if (!line || line.startsWith("#")) return

        def matcher = line =~ /@theorchard\/([\w-]+)/

        if (matcher) {
            def team = matcher[0][1]

            // capture first orchard team anywhere (as fallback)
            if (!firstTeam) firstTeam = team

            // capture * team and stop scanning further
            if (line.startsWith("*") && !defaultTeam) {
                defaultTeam = team
            }
        }
    }

    def finalTeam = defaultTeam ?: firstTeam

    if (finalTeam) {
        echo "Detected team from CODEOWNERS: ${finalTeam}"
    } else {
        echo "No valid @theorchard team found in CODEOWNERS."
    }

    return finalTeam
}

def updateSonarProjectTags(String sonarUrl, String projectKey, String projectTag) {
    if (!projectTag) {
        echo "No tags specified. Skipping tag update for project '${projectKey}'."
        return
    }

    echo "Updating SonarQube project tags for '${projectKey}' → [${projectTag}]"

    def response = sh(script: """
        set +x
        curl -X POST \
            -u \${SONAR_TOKEN}: \
            -d "project=${projectKey}" \
            -d "tags=${projectTag}" \
            '${sonarUrl}/api/project_tags/set'
    """, returnStdout: true).trim()
}

def getSonarQualityGateStatus(String sonarUrl, String projectKey) {
    def response = sh(script: """
        set +x
        curl -s -u \$SONAR_TOKEN: \\
        '${sonarUrl}/api/qualitygates/project_status?projectKey=${projectKey}'
    """, returnStdout: true).trim()

    def json = new JsonSlurper().parseText(response)
    if (json?.errors) {
        echo "Project '${projectKey}' not found in quality gate API."
        return "ERROR"
    }
    return json.projectStatus.status
}

def getSonarCurrentProjectVersion(String sonarUrl, String projectKey) {
    def response = sh(script: """
        set +x
        curl -s -u \$SONAR_TOKEN: \\
        '${sonarUrl}/api/project_analyses/search?project=${projectKey}&ps=1'
    """, returnStdout: true).trim()

    def json = new JsonSlurper().parseText(response)
    if (json?.errors) {
        echo "Project '${projectKey}' not found in SonarQube analyses. Defaulting to version 1.0"
        return "1.0"
    }
    def analyses = json.analyses
    return analyses ? analyses[0].projectVersion : '1.0'
}

def incrementVersion(String version) {
    def parts = version.tokenize('.').collect { it.toInteger() }
    if (parts.size() == 1) {
        parts << 0
    }
    parts[-1] = parts[-1] + 1
    return parts.join('.')
}

def call(Map args) {
    assert (args.project && args.language): 'project and language are required arguments'
    def scannerHome = tool 'SonarQubeScanner'
    def exclusions = args.exclusions ?: 'dev/**,fargate/**,tests/**,dockerToEcr/**,dockerScan/**,fargateDeploy/**,lambdaDeploy/**'
    def projectBaseDir = args.projectBaseDir ?: ''
    def qualityGateWait = args.qualityGateWait != null ? args.qualityGateWait : true
    def qualityGateTimeout = args.qualityGateTimeout ?: 60
    def projectVersion = '1.0'
    def codeOwnerFileDir = args.codeOwnerFileDir ?: env.WORKSPACE
    def additionalProperties = args.additionalProperties ?: [:]
    assert additionalProperties instanceof Map: 'additionalProperties must be a Map'
    echo "Running Sonar scanner for ${args.project}"

    def SONAR_URL = 'https://prod-sonar.theorchard.io'
    def PROJECT_KEY = args.project

    // Perform clean checkout to a subdirectory to ensure there are no workspace artifacts in the analysis
    dir("sonar-scanner-temp") {
        checkout scm

        def teamTag = getTeamFromCodeowners(codeOwnerFileDir)
        def projectDir = projectBaseDir != '' ? "${pwd()}/${projectBaseDir}" : pwd()

        withCredentials([string(credentialsId: 'prod_sonar_security_token', variable: 'SONAR_TOKEN')]) {
            // ==== Get Quality Gate Status ====
            def gateStatus = getSonarQualityGateStatus(SONAR_URL, PROJECT_KEY)
            echo "Quality Gate Status: ${gateStatus}"

            // ==== Get Current Version ====
            def currentVersion = getSonarCurrentProjectVersion(SONAR_URL, PROJECT_KEY)
            echo "Current Project Version: ${currentVersion}"

            // ==== Decide Next Version ====
            projectVersion = (gateStatus == 'ERROR') ? currentVersion : incrementVersion(currentVersion)
            echo "Using Project Version: ${projectVersion}"

            def additionalFlags = additionalProperties.collect { k, v -> "-D${k}=${v}" }.join(" \\\n                        ")
            nodejs(nodeJSInstallationName: 'nodejs 18.20.6') {
                withSonarQubeEnv(installationName: 'prod-sonar.theorchard.io') {
                    sh """
                        ${scannerHome}/bin/sonar-scanner \
                        -Dsonar.language=${args.language} \
                        -Dsonar.projectName=${args.project} \
                        -Dsonar.projectVersion=${projectVersion} \
                        -Dsonar.sourceEncoding=UTF-8 \
                        -Dsonar.projectKey=${args.project} \
                        -D'sonar.exclusions=${exclusions}' \
                        -Dsonar.sources=. \
                        -Dsonar.projectBaseDir=${projectDir} \
                        -Dsonar.qualitygate.wait=${qualityGateWait} \
                        -Dsonar.qualitygate.timeout=${qualityGateTimeout} \
                        ${additionalFlags}
                    """
                }
            }

            // ==== Attach Teams Tags to Project====
            if (teamTag) {
                updateSonarProjectTags(SONAR_URL, PROJECT_KEY, teamTag)
            }
        }

        deleteDir() // Clean up temp directory
    }
}
