def cicdproject = "${CI_CD_NAMESPACE}"
def appname = "${APP_NAME}"
def devproject = "${DEV_NAMESPACE}"
def i1project = "${I1_NAMESPACE}"
def u1project = "${U1_NAMESPACE}"
def t1project = "${T1_NAMESPACE}"
def jenkinsslave = "nodejs12-agent"

pipeline {

  agent {
      node {label "${jenkinsslave}"}
  }

  environment {
      CURRENT_COMMIT = getShortCommitHash()
      BUILD_TAG = ""
  }

  stages {

    stage("Initialize") {
      steps {
        echo '### Generating build tag... ###'
        script {
          def packageJson = readJSON file: 'package.json'
          BUILD_TAG = "dev_v${packageJson.version}_${env.BUILD_NUMBER}_${CURRENT_COMMIT}"
          echo '### Build tag ###'
          echo "${BUILD_TAG}"
        }
        echo '### Build tag generated! ###'
      }
    }

    stage("Install dependencies") {
      environment {
        NEXUS_CREDS = "${env.NEXUS_USERNAME}:${env.NEXUS_PASSWORD}"
      }
      steps {
        echo '### Installing dependencies... ###'
        sh '''
          ENCODED=$(echo -n "${NEXUS_CREDS}" | openssl base64)
          CACHE_DIRECTORY=/home/jenkins/.npm/cache
          mkdir -p ${CACHE_DIRECTORY}
          echo "_auth=${ENCODED}" >> .npmrc
          # set -x
          cat .npmrc

          # Pull from cache if it exists
          (
            # Fail if any step fail
            set -e
            # Remove line 3 from package-lock, which contain the package.json version. Store backup.
            # We only care about dependencies, not the version
            sed -i.bak -e '3d' package-lock.json
            # Hash the package-lock.json file
            sha1sum package-lock.json | tr -s " " | awk '{print $1}' > hashed.pkg-lock
            # Restore package-lock.json with version number intact
            mv package-lock.json.bak package-lock.json
            # Try to get the file from cache
            cp ${CACHE_DIRECTORY}/$(cat hashed.pkg-lock) node_modules.tar.gz 2> /dev/null
            # Check if we found the cached node_modules
            test -f node_modules.tar.gz
            # If we found the cached node_modules, extract the files to node_modules
            tar -zxf node_modules.tar.gz
            # Echo to the logs stating that we are using cache
            echo "Using cached node_modules from ${CACHE_DIRECTORY}/$(cat hashed.pkg-lock)"
          ) || true

          # If we did not find the cached node_modules, install from the lock
            test -f node_modules.tar.gz || npm ci;

          # Store cache
          (
            # Fail if any step fail
            set -e
            # Only update the cache if we found no previous cache
            test ! -f node_modules.tar.gz
            # Tar the cache
            tar -zcf node_modules.tar.gz node_modules
            # Clean old cache
            rm -rf ${CACHE_DIRECTORY}/*
            # Store the cache
            cp node_modules.tar.gz ${CACHE_DIRECTORY}/$(cat hashed.pkg-lock)
          ) || true
        '''
        echo '### Dependencies installed! ###'
      }
    }

    stage("Build application") {
      steps {
        echo '### Building application... ###'

         sh '''
           npm run build -- --output-path=dist
           cp -r nginx/* dist/.
        '''

        // Used when testing Openshift, so that we dont need to wait for build. Also put a # before npm ci above
        // sh '''
        //   mkdir dist
        //   echo hello > dist/index.html
        // '''

        echo '### Application built! ###'
      }
    }
    stage('App bake') {
      steps {
        echo '### Creating image... ###'
        script {
          openshift.withCluster() {
            openshift.withProject(devproject) {
              openshift.selector("bc", "${ appname }").startBuild("--from-dir=./dist", "--wait=true")
              openshift.tag("${ appname }:latest", "${ appname }:${BUILD_TAG}")
            }
          }
        }
        echo '### Image created! ###'
      }
    }

    stage('Deploy u1') {
      steps {
        echo '### Deploying to U1... ###'
        script {
          openshift.withCluster() {
            openshift.withProject(u1project) {
              openshift.raw("set image dc/${ appname } ${ appname }=docker-registry.default.svc:5000/${devproject}/${ appname }:${BUILD_TAG} --record=true --source=docker")
              openshift.raw("annotate dc ${ appname }  version=${BUILD_TAG} --overwrite=true")
              openshift.selector("dc", "${ appname }").rollout().status();
            }
          }
        }
        echo '### Deployed to U1! ###'
      }
    }

    stage('Deploy i1') {
      steps {
        echo '### Deploying to I1... ###'
        script {
          openshift.withCluster() {
            openshift.withProject(i1project) {
              openshift.raw("set image dc/${ appname }  ${ appname }=docker-registry.default.svc:5000/${devproject}/${ appname }:${BUILD_TAG} --record=true --source=docker")
              openshift.raw("annotate dc ${ appname }  version=${BUILD_TAG} --overwrite=true")
              openshift.selector("dc", "${ appname }").rollout().status();
            }
          }
        }
        echo '### Deployed to I1! ###'
      }
    }

    stage('Deploy t1') {
      steps {
        echo '### Deploying to T1... ###'
        script {
          openshift.withCluster() {
            openshift.withProject(t1project) {
              openshift.raw("set image dc/${ appname }  ${ appname }=docker-registry.default.svc:5000/${devproject}/${ appname }:${BUILD_TAG} --record=true --source=docker")
              openshift.raw("annotate dc ${ appname }  version=${BUILD_TAG} --overwrite=true")
              openshift.selector("dc", "${ appname }").rollout().status();
            }
          }
        }
        echo '### Deployed to T1! ###'
      }
    }

  }
}

def getShortCommitHash() {
  return sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
}
