#!groovy​

node {

    def THEME = "northwest-theme"
    def REPO = "ncahec/${THEME}"
    def TAG = "${env.BRANCH_NAME}-${env.BUILD_NUMBER}"
    def DOCKER_COMPOSE_PROJECT_NAME = "ncahec"
    def SLACK_CHANNEL = "#northwest-theme"
    def SLACK_TOKEN = "eMrENXHCDXZcTUZSbZQeUTZV"
    def SLACK_TEAM = 'ncahec'
    def error = null
    def ERROR_MESSAGE = ''
    def AWS_REGION = "us-east-1"
    def AWS_BUCKET = "ahec-frontend"
    def BUILD_COLOR = "good"
    def BUILD_RESULT = "succeeded"
    def BUILD_MESSAGE = ''
    def NPM_VERSION = ''
    def LOCATION = ''
    def BUILD_IMAGE_TAG = 'northwest_theme_build_image'
    def GIT_TAG= ''

    try {
            
        stage('Clone') {
            
            // report status to slack
            slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "commencing job ${REPO}:${env.BRANCH_NAME}-${env.BUILD_NUMBER}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

            // clear directory
            deleteDir()

            // report status to slack
            slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "cloning ${REPO}:${env.BRANCH_NAME}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

            // clone repo and get tags
            sh("git clone --depth 1 git@bitbucket.org:${REPO} -b ${env.BRANCH_NAME} .")
            sh("git fetch --tags")
            sh("git config user.email \"jenkins@ncahec.net\"")
            sh("git config user.name \"ncahec jenkins\"")

        }

        stage('npm install') {
            
            // report status to slack
            slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "installing npm modules", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

            // install npm_modules
            // sh("npm install")
            // set the package version to 0.0.0 so we can cache npm modules if they have not changed
            sh("npm --no-git-tag-version version 0.0.0")
            sh("docker build -t ${BUILD_IMAGE_TAG} .")
            // reset the package version 
            sh("git reset --hard HEAD")

        }

        stage('Verify Version') {
            slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "Checking build version ${REPO}:${env.BRANCH_NAME}@${NPM_VERSION}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

            sh('npm run get-version -s > npm_version')
            NPM_VERSION = readFile('npm_version').trim()
            LOCATION = "themes/${THEME}/${env.BRANCH_NAME}/${NPM_VERSION}"
            try{
                // if there is no tag we should continue with the build. 
                // will throw an error if no tag is set
                sh("git describe > gittag")
                CURRENT_GIT_TAG = readFile('gittag').trim()
                // aborted because there is a tag
                currentBuild.result = 'ABORTED'
            }
            catch(err){
                e = "Reading git tag: ${err}";
                echo(e);
            }
            finally{
                if ( currentBuild.result == 'ABORTED'){
                    slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "Commit tagged ( ${CURRENT_GIT_TAG} ) ${REPO}:${env.BRANCH_NAME}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"
                    stage('Build AND Publish to AWS S3') {}
                    stage("Tag Repo"){}
                    return;
                }
                // if error is thrown then there are no tags
                CURRENT_GIT_TAG = ''
            }

            // bump the version.  Will only be commited if successful
            
            if ( "${env.BRANCH_NAME}" == 'master' ) {
                sh("npm version minor")
            } else {
                sh("npm version patch")
            }

            // get version
            sh('npm run get-version -s > npm_version')
            NPM_VERSION = readFile('npm_version').trim()
            sh("git tag -d v${NPM_VERSION}")

            // update location with latest version
            LOCATION = "themes/${THEME}/${env.BRANCH_NAME}/${NPM_VERSION}"
            LATEST= "themes/${THEME}/${env.BRANCH_NAME}/latest"

            BUILD_MESSAGE = "https://s3.amazonaws.com/${AWS_BUCKET}/${LOCATION}/dist/index.html"
            GIT_TAG = "${BRANCH_NAME}/${NPM_VERSION}"


            // attempt to tag this build with the version.  If tag already exists then fail.
            try{
                sh("git commit --amend -m'${GIT_TAG} (${BUILD_MESSAGE})'")
                sh("git tag ${GIT_TAG} -m \"BUILD ${GIT_TAG}\"")
            }
            catch(err){
                currentBuild.result = 'FAILURE'
                BUILD_MESSAGE = "Error: ${THEME}/${env.BRANCH_NAME}/${NPM_VERSION} already exists"
                stage('Build AND Publish to AWS S3') {}
                stage("Tag Repo"){}
                return; 
            }
        
        // PRINT TO LOG FILE NOT WORKING
        
        //     // report status to slack
        //     slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "verifying npm package version ${REPO}:${env.BRANCH_NAME}@${NPM_VERSION}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

        //     // ck s3 to see if version exists
        //     sh("aws s3 ls s3://${AWS_BUCKET}/${LOCATION}/ &> version-exists.log")

        //     def VERSION_EXISTS = readFile('version-exists.log')
        
        //     println(VERSION_EXISTS.trim().length())
        
        //     if(VERSION_EXISTS.trim().length() > 0){
        //         BUILD_MESSAGE = "Error: ${THEME}/${env.BRANCH_NAME}/${NPM_VERSION} already exists"
        //         throw new IOException();
        //     }
        
        }

        if ( currentBuild.result == 'ABORTED'){
            slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "aborted ${REPO}:${env.BRANCH_NAME}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"
            return;
        }
        if ( currentBuild.result == 'FAILURE'){
            slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "failed ${REPO}:${env.BRANCH_NAME}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"
            return;
        }

        stage('Build AND Publish to AWS S3') {

            // report status to slack
            slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "publishing ${REPO}:${env.BRANCH_NAME}@${NPM_VERSION} to AWS S3", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

            // store to aws s3 /${AWS_BUCKET}/themes/${THEME}/${NPM_VERSION}/dist/
            SCRIPT = "source ~/.bash_profile"
            SCRIPT = "${SCRIPT}\nset -x"
            SCRIPT = "${SCRIPT}\nnpm run start"
            SCRIPT = "${SCRIPT}\naws s3api put-object --bucket ${AWS_BUCKET} --key ${LOCATION}/dist/"
            SCRIPT = "${SCRIPT}\naws s3 mv ~/app/dist/ \"s3://${AWS_BUCKET}/${LOCATION}/dist/\" --recursive --acl public-read"
            SCRIPT = "${SCRIPT}\naws s3api put-object --bucket ${AWS_BUCKET} --key ${LATEST}/dist/"
            SCRIPT = "${SCRIPT}\naws s3 --debug mv ~/app/dist/ \"s3://${AWS_BUCKET}/${LATEST}/dist/\" --recursive --acl public-read"
            

            sh("mkdir script")
            sh("echo \"${SCRIPT}\">script/script.sh")
            sh("chmod +x script/script.sh")
            sh("cat script/script.sh")

            HOME_PATH = "/efs/jenkins/var/jenkins_home"
            WORKSPACE_PATH = "${HOME_PATH}/workspace"
            sh("folder=\${PWD##*/}&&docker run -v ${WORKSPACE_PATH}/\${folder}/package.json:/home/node/app/package.json -v ${HOME_PATH}/.aws:/home/node/.aws -v ${WORKSPACE_PATH}/\${folder}/script:/home/node/app/script ${BUILD_IMAGE_TAG}:latest bash script/script.sh")

        }

        stage('Tag Repo'){
            sh("git push origin --tags&&git push origin")
        }

        stage('Publish to npm') {

            // report status to slack
            slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "publishing ${REPO}:${env.BRANCH_NAME}@${NPM_VERSION} to npm", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

            // store to npm
            sh("npm publish")
        
        }

    } catch (err) {

        e= "${err}";
        echo(e);
        error = err
        BUILD_RESULT = "failed"
        BUILD_COLOR = "danger"

        // report publish status to slack
        // slackSend channel: "${SLACK_CHANNEL}", color: "danger", message: "${ACTION} failed: ${IMAGE}:${TAG}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

    } finally {

        // report publish status to slack
        slackSend channel: "${SLACK_CHANNEL}", color: "${BUILD_COLOR}", message: "publish ${THEME}:${NPM_VERSION} ${BUILD_RESULT}\n${BUILD_MESSAGE}", teamDomain: "${SLACK_TEAM}", token: "${SLACK_TOKEN}"

        stage('Clean up') {

            // clear directory
            deleteDir()
        
        }

        if (error) {
            throw error
        }
    }
}