String GITHUB_REPOSITORY = 'preference-center-web'
String ECR_ACCOUNT_ID = '086679231553'
List<String> AWS_REGIONS = ['us-east-1']
String QA_ACCOUNT_ID = '285943604611'
String QA_DEPLOYMENT_ROLE = 'qa-jenkins-pipeline-deploy-role'
String QA_SENTRY_DSN = 'https://bacf8c6e2d2a0f724f058417ab90fe24@o22178.ingest.sentry.io/4506581129297920'
String PROD_SENTRY_DSN = 'https://8887214cdeb513ff8a4f5a1252936d75@o22178.ingest.us.sentry.io/4507984582737920'
String PROD_ACCOUNT_ID = '737325105821'
String PROD_DEPLOYMENT_ROLE = 'prod-jenkins-pipeline-deploy-role'
String SLACK_NOTIFICATIONS_CHANNEL = '#fansifter-alerts'
String SLACK_BUILDS_CHANNEL = '#fansifter-builds'
String SLACK_E2E_NOTIFY_CHANNEL = '#e2e-test-results'
String POEDITOR_PROJECT_ID = '701178'

pipeline {
    agent any

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

    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.')
        choice(name: 'SKIP_E2E_TESTS', choices: ['No', 'Yes'], description: 'Whether or not to skip e2e tests step')
    }

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

    stages {
        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }
        // stage('Static Application Security Tests') {
        //     steps {
        //         sastTests()
        //     }
        // }
        stage('Style Checks') {
            steps {
                withCredentials([string(credentialsId: 'github_packages_token', variable: 'GITHUB_NPM_TOKEN')]) {
                    sh '''
                        docker compose up \
                            --renew-anon-volumes \
                            --exit-code-from lint \
                            --abort-on-container-exit \
                            --build \
                            --remove-orphans \
                            lint
                    '''
                }
            }
            post {
                cleanup {
                    sh 'docker compose down'
                }
            }
        }
        stage('Unit Tests') {
            steps {
                withCredentials([string(credentialsId: 'github_packages_token', variable: 'GITHUB_NPM_TOKEN')]) {
                    sh '''
                        docker compose up \
                            --renew-anon-volumes \
                            --exit-code-from test \
                            --abort-on-container-exit \
                            --build \
                            --remove-orphans \
                            test
                    '''
                }
            }
            post {
                cleanup {
                    sh 'docker compose down'
                }
            }
        }
        stage('Validate Software Catalog Definitions') {
            steps {
                datadogSoftwareCatalogValidate()
            }
        }
        stage('Compliance Checks') {
            steps {
                complianceChecks()
            }
        }
        stage('Sonar Scan and Analysis') {
            when {
                branch 'master'
            }
            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    sonarScan project: GITHUB_REPOSITORY, language: 'js'
                }
            }
        }
        stage('Create a Release') {
            when {
                branch 'master'
            }
            steps {
                withCredentials([
                    string(credentialsId: 'github_packages_token', variable: 'GITHUB_NPM_TOKEN'),
                    string(credentialsId: 'poeditor-api-token', variable: 'POEDITOR_API_TOKEN')
                ]) {
                    dockerToEcr awsRegions: AWS_REGIONS, ecrAccountId: ECR_ACCOUNT_ID, imageName: GITHUB_REPOSITORY, imageTag: env.GIT_COMMIT,
                        dockerBuildTarget: 'deploy', dockerBuildArgs: [
                            GITHUB_NPM_TOKEN: GITHUB_NPM_TOKEN,
                            POEDITOR_PROJECT_ID: POEDITOR_PROJECT_ID,
                            POEDITOR_API_TOKEN: POEDITOR_API_TOKEN
                        ]
                }
            }
        }
        stage('Deploy to QA') {
            when {
                branch 'master'
            }
            steps {
                fargateDeploy environment: 'qa', awsRegions: AWS_REGIONS, gitCommit: env.GIT_COMMIT, serviceName: GITHUB_REPOSITORY,
                    ecrRegistryAccountId: ECR_ACCOUNT_ID, awsDeploymentTargetAccountId: QA_ACCOUNT_ID, awsDeploymentRoleName: QA_DEPLOYMENT_ROLE
            }
        }
        stage('E2E Tests') {
            when {
                allOf {
                    branch 'master'
                    expression { params.SKIP_E2E_TESTS == 'No' }
                }
            }
            steps {
                playwrightTests tags: "@preference-center"
            }
            post {
                regression {
                    slackNotify channel: SLACK_E2E_NOTIFY_CHANNEL
                }
                fixed {
                    slackNotify channel: SLACK_E2E_NOTIFY_CHANNEL
                }
            }
        }
        stage('Deploy to PROD') {
            when {
                branch 'master'
            }
            steps {
                fargateDeploy environment: 'prod', awsRegions: AWS_REGIONS, gitCommit: env.GIT_COMMIT, serviceName: GITHUB_REPOSITORY,
                    ecrRegistryAccountId: ECR_ACCOUNT_ID, awsDeploymentTargetAccountId: PROD_ACCOUNT_ID, awsDeploymentRoleName: PROD_DEPLOYMENT_ROLE
            }
        }
        stage('Publish Software Catalog Definitions') {
            when {
                branch 'master'
            }
            steps {
                datadogSoftwareCatalogPublish()
            }
        }
    }

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