package com.conio.pipelines.conio_lambda

envMappings = [
//        production: [
//                artifact_bucket: 'conio-bff-sdk-lambda-artifacts',
//                template_bucket: 'conio-bff-sdk-deployments',
//                artifact_region: "eu-west-1",
//                stack_name: 'bff-sdk-prod',
//                api_name: 'bff-sdk-production'
//        ],
        it: [
                artifact_bucket: 'conio-it-staging-bff-sdk-lambda-artifacts',
                template_bucket: 'conio-it-staging-bff-sdk-deployments',
                artifact_region: "eu-west-1",
                stack_name: 'bff-sdk-it',
                api_name: 'conio-sdk-it',
                aws_credentials: 'it-aws'
        ],
        staging: [
                artifact_bucket: 'conio-staging-bff-sdk-artifacts',
                template_bucket: 'conio-staging-bff-sdk-deployment',
                artifact_region: "eu-west-1",
                stack_name: 'bff-sdk-staging',
                api_name: 'conio-sdk-staging',
                aws_credentials: 'staging-aws'
        ],
        hypestaging: [
                artifact_bucket: 'conio-hypestaging-bff-sdk-artifacts',
                template_bucket: 'conio-hypestaging-bff-sdk-deployment',
                artifact_region: "eu-west-1",
                stack_name: 'bff-sdk-hypestaging',
                api_name: 'conio-sdk-hypestaging',
                aws_credentials: 'hypestaging-aws'
        ],
        hype: [
                artifact_bucket: 'conio-hype-bff-sdk-artifacts',
                template_bucket: 'conio-hype-bff-sdk-deployment',
                artifact_region: "eu-west-1",
                stack_name: 'bff-sdk-hype',
                api_name: 'conio-sdk-hype',
                aws_credentials: 'hype-aws'
        ],
        testing: [
                artifact_bucket: 'conio-testing-bff-sdk-artifacts',
                template_bucket: 'conio-testing-bff-sdk-deployment',
                artifact_region: "eu-west-1",
                stack_name: 'bff-sdk-testing',
                api_name: 'conio-sdk-testing',
                aws_credentials: 'testing-aws'
        ]
]
git_commit_short_sha = ""
ecr_repo_url = ""
ecr_repo_name = ""
current_image_name = ""

node("docker") {
    properties([disableConcurrentBuilds()])
    def current_image

    stage('Get commit SHA') {
        checkout scm
        git_commit_short_sha = sh(returnStdout: true, script: 'git rev-parse --short=16 HEAD').trim()
    }

    stage("Build test image") {
        if (env.BRANCH_NAME == 'it' || env.BRANCH_NAME == 'develop') {
            ecr_repo_url = sh(returnStdout: true, script: "aws ecr get-login|awk '{print \$9}'").trim()
            ecr_repo_name = ecr_repo_url.substring(8)
            current_image_name = "${ecr_repo_name}/conio/${env.JOB_NAME}:${git_commit_short_sha}-${env.BUILD_NUMBER}".toString()
            echo "Building docker image ${current_image_name}"
            docker.withRegistry(ecr_repo_url, "ecr:eu-west-1:ecr_key_core") {
                current_image = docker.build(current_image_name, "-f Dockerfile-it .")
            }
        }
    }

    stage("Unit tests") {
        if (env.BRANCH_NAME == 'it' || env.BRANCH_NAME == 'develop') {
            echo "app is ${current_image_name}"
            def current_pwd = sh(returnStdout: true, script: "pwd").trim()
            echo "${current_pwd}"
            sh(script: "docker run -v ${current_pwd}:/app --entrypoint /bin/bash ${current_image_name} -c 'cd /app && CONIO_ENV=ci PYTHONPATH=dist CONIO_WEBSTACK=aws PYTHON_TESTS=1 python3 -m unittest discover test.unit'")
        }
    }

    stage("Integration tests") {
        if (env.BRANCH_NAME == 'it' || env.BRANCH_NAME == 'develop') {
            withCredentials(
                    [
                            [
                                    $class       : 'AmazonWebServicesCredentialsBinding',
                                    credentialsId: "pipeline_ssm_reader",
                            ]
                    ]
            ) {
                def current_pwd = sh(returnStdout: true, script: "pwd").trim()
                sh(script: "docker run -e AWS_SSM_SECRET=${env.AWS_SECRET_ACCESS_KEY} -e AWS_SSM_KEY=${env.AWS_ACCESS_KEY_ID} -v ${current_pwd}:/app --network conio --entrypoint /bin/bash ${current_image_name} -c 'cd /app && CONIO_ENV=it CONIO_WEBSTACK=aws python3 -m unittest discover test.integration'")
            }
        }
    }

}

def stages = [:]

if (env.BRANCH_NAME == 'it') {
    stages['it'] = create_build_environment_stage('it', true)
} else if (env.BRANCH_NAME == 'staging') {
    stages['staging'] = create_build_environment_stage('staging', true)
} else if (env.BRANCH_NAME == 'hypestaging') {
    stages['hypestaging'] = create_build_environment_stage('hypestaging', true)
} else if (env.BRANCH_NAME == 'hype') {
    stages['staging'] = create_build_environment_stage('hype', true)
} else if (env.BRANCH_NAME == 'testing') {
    stages['testing'] = create_build_environment_stage('testing', true)
} else if (env.BRANCH_NAME == 'develop') {
    stages['it'] = create_build_environment_stage('it', true)
    stages['staging'] = create_build_environment_stage('staging', false)
    stages['hypestaging'] = create_build_environment_stage('hypestaging', false)
    //stages['production'] = create_build_environment_stage('production', false)
} else if (env.BRANCH_NAME.startsWith("hotfix/")) {
    stages['it'] = create_build_environment_stage('it', false)
    stages['staging'] = create_build_environment_stage('staging', false)
    stages['hypestaging'] = create_build_environment_stage('hypestaging', false)
    //stages['production'] = create_build_environment_stage('production', false)
}

parallel stages

def create_build_environment_stage(String environment, Boolean shouldUpdateStage) {
    return {
        node("docker") {
            properties([disableConcurrentBuilds()])
            def api_id
            def deployment_id
            def artifact_region
            def template_bucket
            def artifact_bucket
            def stack_name
            def api_name
            def aws_creds

            stage('Checkout') {
                checkout scm
            }

            stage("Variable defs") {
                artifact_region = envMappings[environment]["artifact_region"]
                echo "Artifact region: ${artifact_region}"
                template_bucket = envMappings[environment]["template_bucket"]
                echo "Template bucket: ${template_bucket}"
                artifact_bucket = envMappings[environment]["artifact_bucket"]
                echo "Artifact bucker: ${artifact_bucket}"
                stack_name = envMappings[environment]["stack_name"]
                echo "Stack name: ${stack_name}"
                api_name = envMappings[environment]["api_name"]
                echo "Api name: ${api_name}"
                aws_creds = envMappings[environment]["aws_credentials"]
            }

            stage("Build ${environment} artifact") {
                ecr_repo_url = sh(returnStdout: true, script: "aws ecr get-login|awk '{print \$9}'").trim()
                ecr_repo_name = ecr_repo_url.substring(8)
                docker.withRegistry(ecr_repo_url, "ecr:eu-west-1:ecr_key_core") {
                    def base_image_name = "${ecr_repo_name}/conio/conio-base:latest"
                    def base_image = docker.image(base_image_name)
                    base_image.pull()
                }
                withAWS(
                        credentials: aws_creds,
                        region: artifact_region
                ) {
                    sh("./build_code.sh")
                    sh("CONIO_ENV=${environment} python3 generate_template.py ${artifact_bucket}")
                    sh("cd deploy/dist_${environment} && chmod +x ./deploy_to_aws.sh")
                    sh("cd deploy/dist_${environment} && ./deploy_to_aws.sh")
                }
            }

            stage("Deploy ${environment} artifact") {
                withAWS(
                        credentials: aws_creds,
                        region: artifact_region
                ) {
                    sh("cd deploy/dist_${environment} &&  aws --region ${artifact_region} cloudformation deploy --s3-bucket ${template_bucket} --parameter-overrides ConioEnv=${environment} --capabilities CAPABILITY_NAMED_IAM --template-file template_output.yaml --stack-name ${stack_name}")
                }
            }

            stage("Create ${environment} deployment") {
                withAWS(
                        credentials: aws_creds,
                        region: artifact_region
                ) {
                    api_id = sh(returnStdout: true, script: "aws --region ${artifact_region} apigateway get-rest-apis | jq .items | jq -c '[ .[] | select( .name | contains(\"${api_name}\")) ]' | jq .[0].id").trim()
                    deployment_id = sh(returnStdout: true, script: "aws --region ${artifact_region} apigateway create-deployment --rest-api-id ${api_id} --stage-name ${environment} --description ${git_commit_short_sha} | jq .id").trim()
                }
            }

            stage("Update ${environment} rest-api stage") {
                if (shouldUpdateStage) {
                    withAWS(
                            credentials: aws_creds,
                            region: artifact_region
                    ) {
                        sh("aws --region ${artifact_region} apigateway update-stage --rest-api-id ${api_id} --stage-name ${environment} --patch-operations \"op=replace,path=/deploymentId,value=${deployment_id}\"")
                    }
                }
            }
        }
    }
}
