String GITHUB_REPOSITORY = 'scripts-youtube'
String SLACK_NOTIFICATIONS_CHANNEL = '#distro-build-alerts'
String ECR_ACCOUNT_ID = '086679231553'
List<String> AWS_REGIONS = ['us-east-1']

DIRECTORY_CONFIG = [
    'clear-bacon-history': [
        test: true,
        build: false
    ],
    'clear-cid-delivery-history': [
        test: true,
        build: true
    ],
    'create-bacon-metadata': [
        test: true,
        build: false
    ],
    'update-youtube-channel-cms-account': [
        test: true,
        build: false
    ],
    'youtube-claims-api-support': [
        test: false,
        build: false
    ]
]

pipeline {
    agent none

    options {
        ansiColor('xterm')
        disableConcurrentBuilds()
        timestamps()
    }

    parameters {
        string(
            name: 'DIRECTORIES',
            defaultValue: '',
            description: "Comma-separated list of directories to build. If not specified, all modified directories will be built."
        )
        string(
            name: 'SHARED_LIBRARIES_VERSION',
            defaultValue: 'master',
            description: 'The version of the Jenkins shared libraries to use. Can be a branch, tag, Git revision or PR ref (e.g. pull/PR_NUMBER/merge).'
        )
    }

    triggers {
        issueCommentTrigger('.*retest this please.*')
    }

    stages {
        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }
        stage('Compliance Checks') {
            agent any
            steps {
                complianceChecks()
            }
        }
        stage('Static Application Security Tests') {
            steps {
                withModifiedProjects(checkout: true) { project, config ->
                    sastTests(projectDir: project)
                }
            }
        }
        stage('Unit Tests and Style Checks') {
            steps {
                withModifiedProjects(checkout: true) { project, config ->
                    withEnv(["COMPOSE_PROJECT_NAME=${env.BUILD_TAG.toLowerCase()}-${project.replaceAll('/', '-')}"]) {
                        withEcr {
                            script {
                                if (config.test == true) {
                                    dir(project) {
                                        try {
                                            sh "docker compose run --rm --build lint-and-test"
                                        }
                                        finally {
                                            sh 'docker compose down --remove-orphans'
                                        }
                                    }
                                } else {
                                    echo "No unit tests or style checks configured for project: ${project}"
                                }
                            }
                        }
                    }
                }
            }
        }
        stage('Sonar Scan and Analysis') {
            when {
                branch 'master'
            }
            steps {
                withModifiedProjects(checkout: true) { project, config ->
                    sonarScan project: "${GITHUB_REPOSITORY}-${project.replaceAll('_', '-')}",
                        language: 'python',
                        projectBaseDir: project
                }
            }
        }
        stage('Create a Release') {
            when {
                branch 'master'
            }
            steps {
                withModifiedProjects(checkout: true) { project, config ->
                    script {
                        if (config.build == true) {
                            dockerToEcr awsRegions: AWS_REGIONS,
                                ecrAccountId: ECR_ACCOUNT_ID,
                                imageName: project.replaceAll('_', '-'),
                                imageTag: env.GIT_COMMIT,
                                dockerBuildContext: project,
                                dockerBuildFile: "${project}/Dockerfile",
                                dockerBuildTarget: 'app'
                        } else {
                            echo "No build configured for project: ${project}"
                        }
                    }
                }
            }
        }
    }

    post {
        regression {
            script {
                if (env.BRANCH_NAME == 'master') {
                    slackNotify channel: SLACK_NOTIFICATIONS_CHANNEL
                }
            }
        }
        fixed {
            script {
                if (env.BRANCH_NAME == 'master') {
                    slackNotify channel: SLACK_NOTIFICATIONS_CHANNEL
                }
            }
        }
    }
}

def withModifiedProjects(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,
        projectConfig: DIRECTORY_CONFIG,
        projectsToBuild: params.DIRECTORIES ? params.DIRECTORIES.split(',') : null
    )
}
