String ECR_ACCOUNT_ID = '086679231553'
List<String> AWS_REGIONS = ['us-east-1']
String SLACK_NOTIFICATIONS_CHANNEL = '#devops-internal-alerts'
String IMAGE_OVERRIDE = 'docker-ssh-proxy'

List<String> VULNERABILITIES_TO_IGNORE = [
    'CVE-2023-52425',  // pkg:deb/debian/expat
    'CVE-2026-42496',  // pkg:deb/debian/perl@5.36.0-7%2Bdeb12u3?arch=amd64&distro=bookworm&epoch=0 
    'CVE-2026-48962',  // pkg:deb/debian/perl@5.36.0-7%2Bdeb12u3?arch=amd64&distro=bookworm&epoch=0 
    'CVE-2026-42497',  // pkg:deb/debian/perl@5.36.0-7%2Bdeb12u3?arch=amd64&distro=bookworm&epoch=0 
    'CVE-2026-9538',   // pkg:deb/debian/perl@5.36.0-7%2Bdeb12u3?arch=amd64&distro=bookworm&epoch=0 
    'CVE-2026-5773',   // pkg:deb/debian/perl@5.36.0-7%2Bdeb12u3?arch=amd64&distro=bookworm&epoch=0 
    'CVE-2026-45186'   // pkg:deb/debian/perl@5.36.0-7%2Bdeb12u3?arch=amd64&distro=bookworm&epoch=0 
]


QA_SERVICES = [
        [serviceName: 'songwhip-fivetran-proxy', qaClusterName: 'qa-songwhip-fivetran-proxy', awsDeploymentRoleName: 'qa-songwhip-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '619719722105', awsRegions: ['us-east-1']],
        [serviceName: 'business-solutions-fivetran-proxy', prodClusterName: 'qa-business-solutions-fivetran-proxy', awsDeploymentRoleName: 'qa-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '814622134907', awsRegions: ['us-east-1']],
]

UAT_SERVICES = [
        [serviceName: 'fivetran-rds-proxy', uatClusterName: 'uat-fivetran-rds-proxy', awsDeploymentRoleName: 'uat-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '989790945997', awsRegions: ['us-east-1']],
]

PROD_SERVICES = [
        [serviceName: 'songwhip-fivetran-proxy', prodClusterName: 'prod-songwhip-fivetran-proxy', awsDeploymentRoleName: 'prod-songwhip-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '926734670777', awsRegions: ['us-east-1']],
        [serviceName: 'fivetran-rds-proxy', prodClusterName: 'prod-fivetran-rds-proxy', awsDeploymentRoleName: 'prod-jenkins-aws-pipeline-agent', awsDeploymentTargetAccountId: '437795906767', awsRegions: ['us-east-1']],
        [serviceName: 'looker-rds-proxy', prodClusterName: 'prod-looker-rds-proxy', awsDeploymentRoleName: 'prod-jenkins-aws-pipeline-agent', awsDeploymentTargetAccountId: '437795906767', awsRegions: ['us-east-1']],
        [serviceName: 'sme-rds-proxy', prodClusterName: 'prod-sme-rds-proxy', awsDeploymentRoleName: 'prod-jenkins-aws-pipeline-agent', awsDeploymentTargetAccountId: '437795906767', awsRegions: ['us-east-1']],
        [serviceName: 'grps-fivetran-proxy', prodClusterName: 'prod-grps-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '918817604416', awsRegions: ['eu-central-1']],
        [serviceName: 'business-solutions-fivetran-proxy', prodClusterName: 'prod-business-solutions-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '009424872958', awsRegions: ['us-east-1']],
        [serviceName: 'eom-fivetran-proxy', prodClusterName: 'prod-eom-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '799833541840', awsRegions: ['eu-central-1']],
        [serviceName: 'royaltyshare-fivetran-proxy', prodClusterName: 'prod-royaltyshare-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '290365479392', awsRegions: ['us-west-2']],
        [serviceName: 'aoma-core-fivetran-proxy', prodClusterName: 'prod-aoma-core-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '613871678587', awsRegions: ['eu-central-1']],
        [serviceName: 'amp-fivetran-proxy', prodClusterName: 'prod-amp-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '554998489284', awsRegions: ['eu-central-1']],
        [serviceName: 'aoma-delivery-fivetran-proxy', prodClusterName: 'prod-aoma-delivery-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '023180329437', awsRegions: ['eu-central-1']],
        [serviceName: 'global-ds-fivetran-proxy', prodClusterName: 'prod-global-ds-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '635220336377', awsRegions: ['eu-central-1']],
        [serviceName: 'accounting-fivetran-proxy', prodClusterName: 'prod-accounting-fivetran-proxy', awsDeploymentRoleName: 'prod-jenkins-pipeline-deploy-role', awsDeploymentTargetAccountId: '375914681009', awsRegions: ['us-east-1']],
]

pipeline {
    agent {
        label 'aws'
    }

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

    parameters {
        choice(name: 'DEPLOY_TO_PROD', choices: ['Yes', 'No'], description: 'Whether or not to deploy to prod.')
        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('Compliance Checks') {
            steps {
                complianceChecks()
            }
        }
        stage('Validate Software Catalog Definitions') {
            steps {
                script {
                    parallel(PROD_SERVICES.collectEntries { service ->
                        return [
                            (service.serviceName): {
                                echo "Validating Software Catalog definition for ${service.serviceName}"
                                datadogSoftwareCatalogValidate(
                                    serviceDefinitionFilePath: "software_catalog/${service.serviceName}.yaml",
                                )
                            }
                        ]
                    })
                }
            }
        }
        stage('Create a Release') {
            when {
                branch 'master'
            }
            parallel {
                stage('Publish Main Image') {
                    steps {
                        dockerToEcr awsRegions: AWS_REGIONS,
                                ecrAccountId: ECR_ACCOUNT_ID,
                                imageName: IMAGE_OVERRIDE,
                                imageTag: env.GIT_COMMIT
                    }
                }
            }
        }
        stage('Deploy to QA') {
            when {
                branch 'master'
            }
            steps {
                script {
                    parallel(QA_SERVICES.collectEntries { service ->
                        [
                                (service.serviceName) : {
                                    fargateDeploy environment: 'qa', awsRegions: service.awsRegions, gitCommit: env.GIT_COMMIT,
                                    serviceName: service.serviceName,
                                    clusterName: service.qaClusterName,
                                    ecrRegistryAccountId: ECR_ACCOUNT_ID,
                                    imageNameOverride: IMAGE_OVERRIDE,
                                    awsDeploymentTargetAccountId: service.awsDeploymentTargetAccountId,
                                    awsDeploymentRoleName: service.awsDeploymentRoleName
                        }]
                    })
                }
            }
        }
        stage('Deploy to UAT') {
            when {
                branch 'master'
            }
            steps {
                script {
                    parallel(UAT_SERVICES.collectEntries { service ->
                        [
                                (service.serviceName) : {
                                    fargateDeploy environment: 'uat', awsRegions: service.awsRegions, gitCommit: env.GIT_COMMIT,
                                    serviceName: service.serviceName,
                                    clusterName: service.uatClusterName,
                                    ecrRegistryAccountId: ECR_ACCOUNT_ID,
                                    imageNameOverride: IMAGE_OVERRIDE,
                                    awsDeploymentTargetAccountId: service.awsDeploymentTargetAccountId,
                                    awsDeploymentRoleName: service.awsDeploymentRoleName
                        }]
                    })
                }
            }
        }
        stage('Scan Docker Image') {
            when {
                branch 'master'
            }
            steps {
                dockerScan awsRegion: AWS_REGIONS[0], ecrAccountId: ECR_ACCOUNT_ID, imageName: IMAGE_OVERRIDE, imageTag: env.GIT_COMMIT, vulnerabilitiesToIgnore: VULNERABILITIES_TO_IGNORE
            }
        }
        stage('Deploy to Prod') {
            when {
                allOf {
                    branch 'master'
                    expression { params.DEPLOY_TO_PROD == 'Yes' }
                }
            }
            steps {
                script {
                    parallel(PROD_SERVICES.collectEntries { service ->
                        [
                                (service.serviceName) : {
                                    fargateDeploy environment: 'prod', awsRegions: service.awsRegions, gitCommit: env.GIT_COMMIT,
                                            serviceName: service.serviceName,
                                            clusterName: service.prodClusterName,
                                            ecrRegistryAccountId: ECR_ACCOUNT_ID,
                                            imageNameOverride: IMAGE_OVERRIDE,
                                            awsDeploymentTargetAccountId: service.awsDeploymentTargetAccountId,
                                            awsDeploymentRoleName: service.awsDeploymentRoleName
                                }]
                    })
                }
            }
        }
        stage('Publish Software Catalog Definition') {
            when {
                allOf {
                    branch 'master'
                    expression { params.DEPLOY_TO_PROD == 'Yes' }
                }
            }
            steps {
                script {
                    parallel(PROD_SERVICES.collectEntries { service ->
                        return [
                            (service.serviceName): {
                                echo "Publishing Software Catalog definition for ${service.serviceName}"
                                datadogSoftwareCatalogPublish(
                                    serviceDefinitionFilePath: "software_catalog/${service.serviceName}.yaml",
                                )
                            }
                        ]
                    })
                }
            }
        }
    }
    post {
        always {
            script {
                if (env.BRANCH_NAME == 'master') {
                    slackNotify channel: SLACK_NOTIFICATIONS_CHANNEL
                }
            }
        }
    }
}
