def String PATCH_VERSION = new Date().format('yyMMddHHmm')
def String INTERN_PORT = Math.abs( new Random().nextInt() % (22000 - 21000) ) + 21000
def String SELENIUM_DOCKER_NAME = "selenium-" + System.currentTimeMillis()

pipeline {
	agent { label getPipelineSlaveLabel()  }
	options {
		buildDiscarder(logRotator(numToKeepStr:'10'))
		timestamps()
	}
	environment {
		RELEASE_NAME=asap("getBuildProperty releaseName")
		RETRY_TIMES=asap("getBuildProperty retryTimes")
		NPM_READ_REPOSITORY=asap("getBuildProperty NPM_READ_REPOSITORY")
		NPM_WRITE_REPOSITORY=asap("getBuildProperty NPM_WRITE_REPOSITORY")
		DOCKER_READ_REPOSITORY=asap("getBuildProperty DOCKER_READ_REPOSITORY")
		MAJOR_VERSION=asap("getBuildProperty majorVersion")
		MINOR_VERSION=asap("getBuildProperty minorVersion")
		COMPONENT_VERSION="$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION"
		COMPONENT_NAME=asap("getBuildProperty componentName")
		IMAGE_TAG="$COMPONENT_NAME-image"
		ASAP_PROPERTY_FILE=asap("getBuildProperty ASAP_PROPERTY_FILE")
		DOCKER_OPTS="--rm --user \$(id -u):\$(id -g) -v \$(pwd):/usr/src -w /usr/src -v \$(pwd):/root --env-file ${ASAP_PROPERTY_FILE}"
		NPM="docker run ${DOCKER_OPTS} ${IMAGE_TAG} npm"
		SELENIUM_DOCKER_IMAGE = asap("getBuildProperty SELENIUM_DOCKER_IMAGE")
		SELENIUM_DOCKER_VERSION = asap("getBuildProperty SELENIUM_DOCKER_VERSION")
		SELENIUM_DOCKER_NAME="$SELENIUM_DOCKER_NAME"
		SELENIUM_PORT=4444
		INTERN_PORT="$INTERN_PORT"
	}
	stages {
		stage('Pre-build') {
			when { expression { return env.RELEASE_NAME == env.BRANCH_NAME } }
			steps {
				retry(RETRY_TIMES) {
					script {
						Map scopeMap = [
							'@watsonanalytics':"${NPM_READ_REPOSITORY}",
							'@waca':"${NPM_READ_REPOSITORY}",
							'@businessanalytics':"${NPM_READ_REPOSITORY}"
						]
						asapMakeNpmrc(registry: "${NPM_READ_REPOSITORY}", scopeMap: scopeMap)
					}
					sh "docker build \
						--no-cache \
						--tag ${IMAGE_TAG} \
						--file ./Dockerfile \
						."
				}
			}
		}
		stage('Build') {
			when { expression { return env.RELEASE_NAME == env.BRANCH_NAME } }
			steps {
				retry(RETRY_TIMES) {
					sh "$NPM version $COMPONENT_VERSION"
					sh "$NPM install"
					sh "$NPM run build"
				}
			}
		}
		stage('Setup docker for Selenium') {
			when { expression { return env.RELEASE_NAME == env.BRANCH_NAME } }
			steps {
				retry(RETRY_TIMES) {
					sh (
						label: "Clean up old selenium containers",
						script: "docker rm -f -v ${SELENIUM_DOCKER_NAME} || true"
					)
					sh (
						label: "Run selenium for testing",
						script: "docker run --detach --name ${SELENIUM_DOCKER_NAME} -v /dev/shm:/dev/shm selenium/${SELENIUM_DOCKER_IMAGE}:${SELENIUM_DOCKER_VERSION}" //Maps to port 4444
					)
				}
			}
		}
		stage('Test') {
			when { expression { return env.RELEASE_NAME == env.BRANCH_NAME } }
			environment {
				SELENIUM_SERVER = sh (
						label: "Get selenium server ip",
						script: "docker inspect --format=\'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\' ${SELENIUM_DOCKER_NAME}",
						returnStdout: true
					).trim()
			}
			steps {
				retry(RETRY_TIMES) {
					sh "$NPM run jest-tests"
				}
			}
		}
		stage('Publish Artifact to NPM registry') {
			when { expression { return env.RELEASE_NAME == env.BRANCH_NAME } }
			steps {
				retry(RETRY_TIMES) {
					script{
						def scopeMap = [:]
						scopeMap =[
							'@waca':"${NPM_WRITE_REPOSITORY}",
						]
						asapMakeNpmrc(registry:"${NPM_READ_REPOSITORY}", scopeMap: scopeMap)
						sh "$NPM publish --registry ${NPM_WRITE_REPOSITORY}"
					}
				}
			}
		}
		stage('ASAP Integration testing') {
			when { expression { return env.RELEASE_NAME == env.BRANCH_NAME } }
			steps {
				retry(RETRY_TIMES) {
					script {
						DO_PROMOTE=env.BRANCH_NAME == asap("getBuildProperty releaseName") || env.BRANCH_NAME == 'master'
						asap("setBuildProperty promote=$DO_PROMOTE")
						asap("testAndPromote")
					}
				}
			}
		}
		stage('Trigger Downstream') {
			agent any
			when { expression { return env.RELEASE_NAME == env.BRANCH_NAME } }
			steps {
				retry(RETRY_TIMES) {
					build job: "BusinessAnalytics/glass-foundation/${BRANCH_NAME}", wait: false
				}
			}
		}
	}
	post {
		failure {
			script {
				if(env.RELEASE_NAME == env.BRANCH_NAME) {
					pipelineSlackSendBuildInfo(currentBuild, "", '#ba-glass-builds')
				}
			}
		}
		always {
			sh "docker rm -f -v ${SELENIUM_DOCKER_NAME} || true"
			asapPipelineTeardown()
		}
	}
}
