#!/usr/bin/env groovy

def PROTECTED_BRANCH
def IS_LATEST

def BRANCH_ENV = [
    test: 'test',
    master: 'production',
    beta: 'production'
]

node {
    stage('Setup') {
        env.NODE_ENV = BRANCH_ENV[env.BRANCH_NAME] ?: 'dev'
        PROTECTED_BRANCH = [
            'dev',
            'test',
            'master',
            'main',
            'beta'
        ]

        IS_PROTECTED_BRANCH = PROTECTED_BRANCH.contains(env.BRANCH_NAME)
        IS_LATEST = ['master', 'main'].contains(env.BRANCH_NAME)

       // https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
        echo "NODE_NAME: ${env.NODE_NAME}"
        echo "WORKSPACE: ${env.WORKSPACE}"
        echo "CHANGE_TARGET: ${env.CHANGE_TARGET}"

        configFileProvider([
            configFile(fileId: 'salix-front.properties',
            variable: 'PROPS_FILE')
        ]) {
            def props = readProperties file: PROPS_FILE
            props.each {key, value -> env."${key}" = value }
            props.each {key, value -> echo "${key}: ${value}" }
        }

        if (IS_PROTECTED_BRANCH) {
            configFileProvider([
                configFile(fileId: "salix-front.branch.${env.BRANCH_NAME}",
                variable: 'BRANCH_PROPS_FILE')
            ]) {
                def props = readProperties file: BRANCH_PROPS_FILE
                props.each {key, value -> env."${key}" = value }
                props.each {key, value -> echo "${key}: ${value}" }
            }
        }
    }
}

pipeline {
    agent any
    options {
        disableConcurrentBuilds()
    }
    tools {
        nodejs 'node-v18'
    }
    environment {
        PROJECT_NAME = 'lilium'
    }
    stages {
        stage('Version') {
            when {
                expression { IS_PROTECTED_BRANCH }
            }
            steps {
                script {
                    def packageJson = readJSON file: 'package.json'
                    def version = "${packageJson.version}-build${env.BUILD_ID}"
                    writeFile(file: 'VERSION.txt', text: version)
                    echo "VERSION: ${version}"
                }
            }
        }
        stage('Install') {
            environment {
                NODE_ENV = ""
            }
            steps {
                sh 'pnpm install --prefer-offline'
            }
        }
        stage('Test') {
            when {
                expression { !IS_PROTECTED_BRANCH }
            }
            environment {
                NODE_ENV = ''
                CI = 'true'
                TZ = 'Europe/Madrid'
            }
            parallel {
                stage('Unit') {
                    steps {
                        sh 'pnpm run test:front:ci'
                    }
                    post {
                        always {
                            junit(
                                testResults: 'junit/vitest.xml',
                                allowEmptyResults: true
                            )
                        }
                    }
                }
                stage('E2E') {
                    environment {
                        CREDS = credentials('docker-registry')
                        COMPOSE_PROJECT = "${PROJECT_NAME}-${env.BUILD_ID}"
                        COMPOSE_PARAMS = "-p ${env.COMPOSE_PROJECT} -f test/cypress/docker-compose.yml --project-directory ."
                    }
                    steps {
                        script {
                            sh 'rm -f junit/e2e-*.xml'
                            sh 'rm -rf test/cypress/screenshots'
                            env.COMPOSE_TAG = PROTECTED_BRANCH.contains(env.CHANGE_TARGET) ? env.CHANGE_TARGET : 'dev'

                            def image = docker.build('lilium-dev', '-f docs/Dockerfile.dev docs')

                            sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
                            sh "docker-compose ${env.COMPOSE_PARAMS} pull back"
                            sh "docker-compose ${env.COMPOSE_PARAMS} pull db"
                            sh "docker-compose ${env.COMPOSE_PARAMS} up -d"

                            image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") {
                                sh 'sh test/cypress/cypressParallel.sh 1'
                            }
                        }
                    }
                    post {
                        always {
                            sh "docker-compose ${env.COMPOSE_PARAMS} down -v"
                            archiveArtifacts artifacts: 'test/cypress/screenshots/**/*', allowEmptyArchive: true
                            junit(
                                testResults: 'junit/e2e-*.xml',
                                allowEmptyResults: true
                            )
                        }
                    }
                }
            }
        }
        stage('Build') {
            when {
                expression { IS_PROTECTED_BRANCH }
            }
            environment {
                VERSION = readFile 'VERSION.txt'
            }
            steps {
                script {
                    sh 'quasar build'

                    def baseImage = "salix-frontend:${env.VERSION}"
                    def image = docker.build(baseImage, ".")
                    docker.withRegistry("https://${env.REGISTRY}", 'docker-registry') {
                        image.push()
                        image.push(env.BRANCH_NAME)
                        if (IS_LATEST) image.push('latest')
                    }
                }
            }
        }
        stage('Deploy') {
            when {
                expression { IS_PROTECTED_BRANCH }
            }
            environment {
                VERSION = readFile 'VERSION.txt'
            }
            steps {
                withKubeConfig([
                    serverUrl: "$KUBERNETES_API",
                    credentialsId: 'kubernetes',
                    namespace: 'lilium'
                ]) {
                    sh 'kubectl set image deployment/lilium-$BRANCH_NAME lilium-$BRANCH_NAME=$REGISTRY/salix-frontend:$VERSION'
                }
            }
        }
    }
}