String GITHUB_REPOSITORY = 'songwhip-packages'
String SLACK_CHANNEL = '#songwhip-alerts-dev'

pipeline {
    agent {
        label 'aws'
    }

    parameters {
        string(name: 'SHARED_LIBRARIES_VERSION', defaultValue: 'master', description: 'The version of the Jenkins shared libraries to use. Can be a branch, tag or Git revision.')
    }

    stages {
        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }

        stage('Static Application Security Tests') {
            steps {
                sastTests()
            }
        }

        stage('Validate Software Catalog Definition') {
            steps {
                script {
                    def missingCatalogs = []
                    withModifiedFunctions(checkout: true) { packageName ->
                        def catalogFile = "packages/${packageName}/software-catalog.yaml"
                        if (fileExists(catalogFile)) {
                            datadogSoftwareCatalogValidate(servicePath: "packages/${packageName}")
                        } else {
                            echo "software-catalog.yaml is required for the package: ${packageName}"
                            missingCatalogs << packageName
                        }
                    }
                    if (missingCatalogs) {
                        error("Missing software-catalog.yaml for packages: ${missingCatalogs.join(', ')}")
                    }
                }
            }
            post {
                failure {
                    slackNotify channel: SLACK_CHANNEL, message: "Datadog Software catalog validation FAILED for ${GITHUB_REPOSITORY}. Please check the pipeline logs."
                }
            }
        }

        stage('Tests') {
            steps {
                nodeSh(
                    user: 'root',
                    script: """
                        # install pnpm and dependencies
                        corepack enable
                        pnpm install --frozen-lockfile

                        # run tests
                        pnpm test
                    """
                )
            }
        }   

        stage('Publish Packages') {
            when {
                branch 'master'
            }
            steps {
                nodeSh (
                    user: 'root',
                    script: """
                        corepack enable
                        pnpm install --frozen-lockfile

                        # clean packages
                        pnpm clean

                        # build packages
                        pnpm build

                        # publish packages to GitHub Package Registry
                        pnpm publish --recursive --no-git-checks --registry https://npm.pkg.github.com
                    """
                )
            }
        }

        stage('Publish Software Catalog') {
            when {
                allOf {
                    branch 'master'
                }
            }
            steps {
                script {
                    def modifiedPaths = getModifiedPaths(basePath: 'packages')
                    modifiedPaths.each { pkg ->
                        def catalogFile = "packages/${pkg}/software-catalog.yaml"
                        if (fileExists(catalogFile)) {
                            datadogSoftwareCatalogPublish(serviceDefinitionFilePath: catalogFile)
                        }
                    }
                }
            }
            post {
                failure {
                    slackNotify channel: SLACK_CHANNEL, message: "Datadog Software catalog publish FAILED for ${GITHUB_REPOSITORY}. Please check the pipeline logs."
                }
            }
        }
    }

    post {
        failure {
            cleanWs()
        }
    }
}

def withModifiedFunctions(Map args = [:], Closure steps) {
    getMonorepoUtils().withModifiedProjects(args, steps)
}

def getMonorepoUtils() {
    return library("jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}").com.sonymusic.MonorepoUtils.getInstance(
        steps: this,
        projectBasePath: 'packages',
        projectsToBuild: params.PACKAGE_NAMES ? params.PACKAGE_NAMES.split(',') : null
    )
}

