pipeline {
    agent any

    triggers {
        parameterizedCron('''
            # PROD - Run every hour (excluding midnight, handled below)
            0 1-23 * * * %ENVIRONMENT=prod;MODELS=tag:hourly_playlists tag:priority_playlists;EXCLUDE=tag:playlists_to_build_only_on_PROD_DBT_WAREHOUSE;WAREHOUSE=;CLEAR_CACHE=true;CLONE_TO_FACTS_QA=false
            # PROD - Run at midnight and clone to FACTS QA
            0 0 * * * %ENVIRONMENT=prod;MODELS=tag:hourly_playlists tag:priority_playlists;EXCLUDE=tag:playlists_to_build_only_on_PROD_DBT_WAREHOUSE;WAREHOUSE=;CLEAR_CACHE=true;CLONE_TO_FACTS_QA=true
        ''')
    }

    options {
        ansiColor('xterm')
        disableConcurrentBuilds()
        timestamps()
        buildDiscarder logRotator(
          artifactDaysToKeepStr: '30',
          artifactNumToKeepStr: '100',
          daysToKeepStr: '365',
          numToKeepStr: '1000'
        )
        timeout(time: 3, unit: 'HOURS')
        datadog(
            collectLogs: false,
            tags: [
                "environment:${params.ENVIRONMENT}",
                "models:${params.MODELS}",
                "exclude:${params.EXCLUDE}",
                "warehouse:${params.WAREHOUSE}",
                "clear_cache:${params.CLEAR_CACHE}",
                "clone_to_facts_qa:${params.CLONE_TO_FACTS_QA}"
            ]
        )
    }

    parameters {
        choice(name: 'ENVIRONMENT', choices: ['qa', 'prod'], description: 'The environment to run against.')
        string(name: 'MODELS', defaultValue: 'tag:hourly_playlists tag:priority_playlists', description: 'Specify which models should be built. For example: tag:hourly_playlists')
        string(name: 'EXCLUDE', defaultValue: 'tag:playlists_to_build_only_on_PROD_DBT_WAREHOUSE', description: 'Optionally specify which models should be excluded from the build. For example: tag:playlists_to_build_only_on_PROD_DBT_WAREHOUSE')
        string(name: 'WAREHOUSE', defaultValue: '', description: 'Optionally specify snowflake warehouse used for DBT build. Example: PROD_PLAYLIST_WAREHOUSE')
        booleanParam(name: 'CLEAR_CACHE', defaultValue: false, description: 'To clear all caches after DBT model build')
        booleanParam(name: 'CLONE_TO_FACTS_QA', defaultValue: false, description: 'Clone DBT models to FACTS QA (runs once a day by default)')
    }

    stages {
        stage('Load Shared Libraries') {
            steps {
                script {
                    currentBuild.displayName = "#${currentBuild.number} ${params.ENVIRONMENT} MODELS: ${params.MODELS} CLEAR_CACHE: ${params.CLEAR_CACHE}"
                }
                library "jenkins-global-libraries@master"
            }
        }

        stage('Build models') {
            when {
                 expression {
                     params.MODELS != ''
                 }
            }
            steps {
                script {
                    build job: 'dbt-scheduler-analytics-build-views',
                        parameters: [
                            string(name: 'MODELS', value: params.MODELS),
                            string(name: 'EXCLUDE', value: params.EXCLUDE),
                            string(name: 'SNOWFLAKE_SCHEMA', value: params.ENVIRONMENT == 'prod' ? 'PROD' : 'QA'),
                            string(name: 'QA_SNOWFLAKE_WAREHOUSE', value: params.WAREHOUSE != '' ? params.WAREHOUSE : 'QA_PLAYLIST_WAREHOUSE'),
                            string(name: 'PROD_SNOWFLAKE_WAREHOUSE', value: params.WAREHOUSE != '' ? params.WAREHOUSE : 'PROD_PLAYLIST_WAREHOUSE'),
                            booleanParam(name: 'FORCE_MODEL_UPGRADE', value: true),
                        ]
                }
            }
        }
        stage('Clear cache ows-playlist') {
            when {
                 expression {
                     params.CLEAR_CACHE == true
                 }
            }
            steps {
                script {
                    build job: 'redis-cache-clear',
                    parameters: [
                        string(name: 'REDIS_SERVER', value: params.ENVIRONMENT == 'prod' ? 'master.prod-ows-playlist.oudhyr.use1.cache.amazonaws.com' : 'master.qa-ows-playlist.oudhyr.use1.cache.amazonaws.com'),
                        string(name: 'KEY_PATTERN', value: ''),
                        booleanParam(name: 'USE_TLS', value: true),
                    ]
                }
            }
        }
        stage('Clear cache graphql-analytics') {
            when {
                 expression {
                     params.CLEAR_CACHE == true
                 }
            }
            steps {
                script {
                    build job: 'redis-cache-clear',
                    parameters: [
                        string(name: 'REDIS_SERVER', value: params.ENVIRONMENT == 'prod' ? 'master.prod-graphql-analytics.oudhyr.use1.cache.amazonaws.com' : 'master.qa-graphql-analytics.oudhyr.use1.cache.amazonaws.com'),
                        string(name: 'KEY_PATTERN', value: 'PlaylistAnalytics:* PlaylistAnalyticsByDimension:* PlaylistAnalyticsTimeseries:* PlaylistAnalyticsTimeseriesByDimension:* PlaylistAnalyticsTotalStreamsAndListeners:* PlaylistFollowersTimeseries:* PlacementPositionTS:* PlaylistPlacementCompanyBrands:* PlaylistMetadata:* GSRPlaylistPlacementAnalytics:* PlaylistPlacements:* PlaylistPlacementStreams:* playlist:*'),
                        booleanParam(name: 'USE_TLS', value: true),
                    ]
                }
            }
        }
        stage('Clear cache graphql-knowledge') {
            when {
                 expression {
                     params.CLEAR_CACHE == true
                 }
            }
            steps {
                script {
                    build job: 'redis-cache-clear',
                    parameters: [
                        string(name: 'REDIS_SERVER', value: params.ENVIRONMENT == 'prod' ? 'prod-graphql-knowledge.oudhyr.ng.0001.use1.cache.amazonaws.com' : 'qa-graphql-knowledge.oudhyr.ng.0001.use1.cache.amazonaws.com'),
                        string(name: 'KEY_PATTERN', value: 'Playlist:id:*'),
                    ]
                }
            }
        }
        stage('Clone hourly DBT models to FACTS QA') {
            when {
                expression {
                    params.CLONE_TO_FACTS_QA == true
                }
            }
            steps {
                script {
                    build job: 'clone-dbt-models-to-facts-qa',
                    parameters: [
                        string(name: 'db_refresh_script', value: 'hourly_qa_dbt_models_refresh.sql'),
                    ]
                }
            }
        }
        stage('Clone priority DBT models to FACTS QA') {
            when {
                expression {
                    params.CLONE_TO_FACTS_QA == true
                }
            }
            steps {
                script {
                    build job: 'clone-dbt-models-to-facts-qa',
                    parameters: [
                        string(name: 'db_refresh_script', value: 'priority_qa_dbt_models_refresh.sql'),
                    ]
                }
            }
        }
    }
    post {
        failure {
            script {
                if (params.ENVIRONMENT == 'prod') {
                    slackSend (
                        color: "danger",
                        channel: "#data-alerts",
                        message: """The build ${currentBuild.fullDisplayName} has failed! ${env.JOB_NAME} - #${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)"""
                    )
                }
            }
        }
        aborted {
            script {
                if (params.ENVIRONMENT == 'prod') {
                    slackSend (
                        color: "danger",
                        channel: "#data-alerts",
                        message: """The build ${currentBuild.fullDisplayName} was aborted! ${env.JOB_NAME} - #${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)"""
                    )
                }
            }
        }
    }
}
