def APP_NAME = 'frontend-royalties'
def QA_AUTH0_CLIENT_ID = 'wTcXYKnR8wk4gIe3C8dNGb4PbH0V3JJn'
def PROD_AUTH0_CLIENT_ID = 'Wtll2PF87gArAJN07Csck35g943v6IpP'
def SLACK_NOTIFICATIONS_CHANNEL = '#abacus-devs'

pipeline {
    agent any

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

    parameters {
        booleanParam(name: 'DEPLOY_TO_UAT', defaultValue: true, description: 'Whether or not to deploy to uat.')
        booleanParam(name: 'DEPLOY_TO_PROD', defaultValue: true, 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.')
    }

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

    stages {
        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }
        stage('Compliance Checks') {
            steps {
                complianceChecks()
            }
        }
        stage('Validate Software Catalog Definition') {
            steps {
                datadogSoftwareCatalogValidate()
            }
        }
        stage('Unit Tests and Style Checks') {
            when {
                not {
                    environment name: 'GITHUB_COMMENT', value: 'deploy pri'
                }
            }
            steps {
                yarnRun scriptNames: ['test', 'build']
            }
            post {
                always {
                    clover cloverReportDir: 'coverage', cloverReportFileName: 'clover.xml',
                        healthyTarget: [methodCoverage: 70, conditionalCoverage: 80, statementCoverage: 80],
                        unhealthyTarget: [methodCoverage: 0, conditionalCoverage: 0, statementCoverage: 0],
                        failingTarget: [methodCoverage: 0, conditionalCoverage: 0, statementCoverage: 0]
                    publishHTML (
                        target: [
                            allowMissing: true,
                            alwaysLinkToLastBuild: false,
                            keepAll: false,
                            includes: '**/*',
                            reportDir: 'coverage/lcov-report',
                            reportFiles: 'index.html',
                            reportName: "HTML Coverage Report"
                        ]
                    )
                }
            }
        }
        stage('Static Application Security Tests') {
            steps {
                sastTests()
            }
        }
        stage('Deploy to PR Instance') {
            when {
                environment name: 'GITHUB_COMMENT', value: 'deploy pri'
            }
            steps {
                suiteAppDeployPrInstance (
                    appName: APP_NAME,
                    envVars: [
                        AUTH0_CLIENT_ID: QA_AUTH0_CLIENT_ID,
                        BUILD_ENV: 'qa'
                    ]
                )
            }
        }
        stage('Sonar Scan and Analysis') {
            when {
                branch 'master'
            }
            steps {
                script {
                    echo "Running Sonar scan for ${APP_NAME}"
                    sonarScan project: APP_NAME, language: 'ts'
                }
            }
        }
        stage('Deploy to QA') {
            when {
                branch 'master'
            }
            steps {
                suiteAppBuild (
                    env: 'qa',
                    envVars: [
                        AUTH0_CLIENT_ID: QA_AUTH0_CLIENT_ID,
                        DATADOG_APPLICATION_ID: '58a6e16e-67a1-4358-ac3b-7701f3b7c473',
                        DATADOG_CLIENT_TOKEN: 'pub4f918be028dc50404dd47fb2cf84d12e',
                        BUILD_ENV: 'qa',
                        CHATBOT_URL: 'https://qa-graphql-abacus.theorchard.io'
                    ]
                )

                suiteAppPublish (
                    env: 'qa',
                    appName: APP_NAME
                )
            }
        }
        stage('Invalidate QA CDN') {
            when {
                branch 'master'
            }
            steps {
                cdnInvalidate env: 'qa', appName: APP_NAME
            }
        }
        stage('Smoke Tests') {
            when {
                branch 'master'
            }
            environment {
                TAGS = "@abacus_qa_smoke"
            }
            steps {
                playwrightTests tags: env.TAGS,
                reportSuffix: 'smoke-tests',
                slackNotificationChannels: [SLACK_NOTIFICATIONS_CHANNEL]
            }
        }
        stage('E2E Tests') {
            when {
                branch 'master'
            }
            environment {
                TAGS = "@frontend_royalties"
            }
            steps {
                playwrightTests tags: env.TAGS,
                pnpmSetupScriptName: 'normalize-art-relations-vendor',
                reportSuffix: 'main-e2e-suite',
                envVars: ['USE_DYNAMIC_THROTTLING': 'true', MAX_CONCURRENT_FEATURES: '10'],
                slackNotificationChannels: [SLACK_NOTIFICATIONS_CHANNEL]
            }
        }
        stage('E2E Closing Balances And Adjustments Tests') {
            when {
                branch 'master'
            }
            environment {
                TAGS = "@frontend_royalties_closing_balances_and_adjustments"
            }
            steps {
                lock(resource: 'e2e-tests-documents') {
                    playwrightTests tags: env.TAGS,
                    pnpmSetupScriptName: 'normalize-art-relations-vendor',
                    reportSuffix: 'closing-balances-and-adjustments-results',
                    runtimeEnvironment: 'ecs',
                    slackNotificationChannels: [SLACK_NOTIFICATIONS_CHANNEL]
                }
            }
        }
        stage('E2E Payments') {
            when {
                branch 'master'
            }
            environment {
                TAGS = "@frontend_royalties_payment"
            }
            steps {
                lock(resource: 'e2e-tests-documents') {
                    playwrightTests tags: env.TAGS,
                    pnpmSetupScriptName: 'normalize-art-relations-vendor',
                    reportSuffix: 'payments',
                    runtimeEnvironment: 'ecs',
                    slackNotificationChannels: [SLACK_NOTIFICATIONS_CHANNEL]
                }
            }
        }
        stage('Deploy to UAT') {
            when {
                allOf {
                    branch 'master'
                    expression { params.DEPLOY_TO_UAT }
                }
            }
            steps {
                suiteAppBuild (
                    env: 'uat',
                    envVars: [
                        AUTH0_CLIENT_ID: QA_AUTH0_CLIENT_ID,
                        DATADOG_APPLICATION_ID: '58a6e16e-67a1-4358-ac3b-7701f3b7c473',
                        DATADOG_CLIENT_TOKEN: 'pub4f918be028dc50404dd47fb2cf84d12e',
                        BUILD_ENV: 'uat'
                    ]
                )

                suiteAppPublish (
                    env: 'uat',
                    appName: APP_NAME
                )
            }
        }
        stage('Invalidate UAT CDN') {
            when {
                allOf {
                    branch 'master'
                    expression { params.DEPLOY_TO_UAT }
                }
            }
            steps {
                cdnInvalidate env: 'uat', appName: APP_NAME
            }
        }
        stage('Deploy to Prod'){
            when {
                allOf {
                    branch 'master'
                    expression { params.DEPLOY_TO_PROD }
                }
            }
            steps {
                suiteAppBuild (
                    env: 'prod',
                    envVars: [
                        AUTH0_CLIENT_ID: PROD_AUTH0_CLIENT_ID,
                        DATADOG_APPLICATION_ID: '58a6e16e-67a1-4358-ac3b-7701f3b7c473',
                        DATADOG_CLIENT_TOKEN: 'pub4f918be028dc50404dd47fb2cf84d12e',
                        BUILD_ENV: 'prod',
                        CHATBOT_URL: 'https://prod-graphql-abacus.theorchard.io'
                    ]
                )

                suiteAppPublish (
                    env: 'prod',
                    appName: APP_NAME
                )
            }
        }
        stage('Invalidate Prod CDN') {
            when {
                allOf {
                    branch 'master'
                    expression { params.DEPLOY_TO_PROD }
                }
            }
            steps {
                cdnInvalidate env: 'prod', appName: APP_NAME
            }
        }
        stage('Publish Software Catalog') {
            when {
                allOf {
                    branch 'master'
                }
            }
            steps {
                datadogSoftwareCatalogPublish()
            }
        }
    }
    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
                }
            }
        }
        cleanup {
            cleanWs()
        }
    }
}
