def main() {

    def pdImage = params.PD_IMAGE
    def tikvImage = params.TIKV_IMAGE
    def tidbImage = params.TIDB_IMAGE
    if (!pdImage.contains(':')) { pdImage = "${pdImage}:${params.VERSION}" }
    if (!tikvImage.contains(':')) { tikvImage = "${tikvImage}:${params.VERSION}" }
    if (!tidbImage.contains(':')) { tidbImage = "${tidbImage}:${params.VERSION}" }

    def tcName = env.NODE_NAME
    def tcSpec = """---
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
  name: ${tcName}
spec:
  pvReclaimPolicy: Delete
  discovery: {}
  pd:
    image: ${pdImage}
    replicas: 1
    requests:
      storage: "1Gi"
    config: {}
  tikv:
    image: ${tikvImage}
    replicas: 1
    requests:
      storage: "1Gi"
    config: {}
  tidb:
    image: ${tidbImage}
    replicas: 1
    service:
      type: ClusterIP
    config: {}
"""
    def poolConfig = """---
staticDBPool:
- host: ${tcName}-tidb
  port: 4000
  status_port: 10080
  user: root
  pass: ''
  type: TiDB
  tags: ['${params.VERSION}']
"""

    stage('Build Once') {
        container('golang') {
            sh("chown -R 1000:1000 ./")
            checkout(changelog: false, poll: false, scm: [
                $class           : "GitSCM",
                branches         : [[name: params.BRANCH]],
                userRemoteConfigs: [[url: "https://github.com/pingcap/qa.git", credentialsId: "github-sre-bot",
                                     refspec: "+refs/heads/*:refs/remotes/origin/* +refs/pull/*/head:refs/remotes/origin/pr/*"]],
                extensions       : [[$class: 'PruneStaleBranch'], [$class: 'CleanBeforeCheckout']],
            ])
            withCredentials([usernameColonPassword(credentialsId: 'github-sre-bot', variable: "GH_AUTH")]) {
                dir("once") {
                    sh("""
                    git config --global credential.helper store
                    echo "https://$GH_AUTH@github.com" > /root/.git-credentials
                    make
                    """)
                }
            }
        }
    }
    try {
        stage('Setup Cluster') {
            container('kubectl') {
                sh("chown -R 1000:1000 ./")
                writeFile(file: 'tc.yaml', text: tcSpec)
                dir('once/build') {
                    writeFile(file: 'pool.yaml', text: poolConfig)
                    writeFile(file: 'values.yaml', text: params.VALUES)
                }
                sh("kubectl apply -f tc.yaml")
                timeout(10) {
                    sh("while ! curl -s -m 20 --fail ${tcName}-tidb:10080/status ; do sleep 10; done")
                }
                sleep(time: 15, unit: 'SECONDS')
            }
            container('golang') {
                dir('once/build') {
                    sh("""
                    pkill -9 resource-pool || sleep 3
                    nohup bin/resource-pool -c pool.yaml &
                    sleep 2
                    while ! curl -s -m 20 --fail 127.0.0.1:8080/resource-pool/tidb ; do sleep 2; done
                    """)
                }
            }
        }

        stage("Run Once") {
            container('golang') {
                dir('once/build') {
                    try {
                        sh("RESOURCE_POOL_ENDPOINT=http://127.0.0.1:8080 bin/testkit run --template conf/template.yaml --values values.yaml")
                    } catch (e) {
                        archiveArtifacts(artifacts: "report.json,testkit.log,pool.yaml,values.yaml")
                        throw e
                    }
                }
            }
        }

    } finally {
        stage('Teardown Cluster') {
            container('kubectl') {
                if (fileExists('tc.yaml')) {
                    sh("""
                    kubectl delete -f tc.yaml || true
                    kubectl delete pvc -l app.kubernetes.io/instance=${tcName}
                    """)
                }
            }
            container('golang') { sh("pkill -9 resource-pool || true") }
        }
    }
}


def run(label, image, Closure body) {
    podTemplate(name: label, label: label, idleMinutes: 60, instanceCap: 5, serviceAccount: 'utf-runner', containers: [
        containerTemplate(name: 'golang', image: image, alwaysPullImage: true, ttyEnabled: true, command: 'cat'),
        containerTemplate(name: 'kubectl', image: 'hub.pingcap.net/qa/kubetools:20200730', alwaysPullImage: false, ttyEnabled: true, command: 'cat'),
    ]) { node(label) { body() } }
}

catchError {
    run('once-test', 'hub.pingcap.net/mirrors/golang:1.14') { main() }
}
