pipeline {
  agent {
    kubernetes {
      label 'pegasus-tests'
      defaultContainer 'go-tester'
      yaml """
apiVersion: v1
kind: Pod
spec:
  nodeSelector:
    kubernetes.io/arch: arm64
    node-role.kubernetes.io/worker: "true"
  containers:
    - name: go-tester
      image: golang:1.22-bookworm
      command: ["cat"]
      tty: true
      volumeMounts:
        - name: workspace-volume
          mountPath: /home/jenkins/agent
    - name: node-tester
      image: node:20-bookworm
      command: ["cat"]
      tty: true
      volumeMounts:
        - name: workspace-volume
          mountPath: /home/jenkins/agent
    - name: publisher
      image: python:3.12-slim
      command: ["cat"]
      tty: true
      volumeMounts:
        - name: workspace-volume
          mountPath: /home/jenkins/agent
  volumes:
    - name: workspace-volume
      emptyDir: {}
"""
    }
  }

  environment {
    SUITE_NAME = 'pegasus'
    PUSHGATEWAY_URL = 'http://platform-quality-gateway.monitoring.svc.cluster.local:9091'
  }

  options {
    disableConcurrentBuilds()
  }

  triggers {
    pollSCM('H/5 * * * *')
  }

  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }

    stage('Backend unit tests') {
      steps {
        container('go-tester') {
          sh '''
            set -eu
            export PEGASUS_SESSION_KEY=test-session-key
            export PEGASUS_COOKIE_INSECURE=1
            mkdir -p build
            cd backend
            go install github.com/jstemmer/go-junit-report/v2@latest
            set +e
            go test -coverprofile=../build/coverage-backend.out ./... > ../build/backend-test.out 2>&1
            test_rc=$?
            set -e
            cat ../build/backend-test.out
            "$(go env GOPATH)/bin/go-junit-report" < ../build/backend-test.out > ../build/junit-backend.xml
            coverage="0"
            if [ -f ../build/coverage-backend.out ]; then
              coverage="$(go tool cover -func=../build/coverage-backend.out | awk '/^total:/ {gsub("%","",$3); print $3}')"
            fi
            printf '%s\n' "${coverage}" > ../build/coverage-backend-percent.txt
            printf '%s\n' "${test_rc}" > ../build/backend-test.rc
          '''
        }
      }
    }

    stage('Frontend unit tests') {
      steps {
        container('node-tester') {
          sh '''
            set -eu
            mkdir -p build
            cd frontend
            npm ci
            set +e
            npm run test:ci > ../build/frontend-test.out 2>&1
            test_rc=$?
            set -e
            cat ../build/frontend-test.out
            if [ -f ../build/frontend-coverage/coverage-summary.json ]; then
              node -e 'const fs=require("fs");const p=JSON.parse(fs.readFileSync("../build/frontend-coverage/coverage-summary.json","utf8"));const pct=((p.total||{}).lines||{}).pct||0;process.stdout.write(String(pct));' > ../build/coverage-frontend-percent.txt
            else
              echo "0" > ../build/coverage-frontend-percent.txt
            fi
            printf '%s\n' "${test_rc}" > ../build/frontend-test.rc
          '''
        }
      }
    }

    stage('Quality gate report') {
      steps {
        container('publisher') {
          sh '''
            set -eu
            python -m testing.pegasus_gate report
          '''
        }
      }
    }

    stage('Publish test metrics') {
      steps {
        container('publisher') {
          sh '''
            set -eu
            python scripts/publish_test_metrics.py
          '''
        }
      }
    }

    stage('Quality gate') {
      steps {
        container('publisher') {
          sh '''
            set -eu
            python -m testing.pegasus_gate enforce
          '''
        }
      }
    }
  }

  post {
    always {
      script {
        if (fileExists('build/junit-backend.xml') || fileExists('build/junit-frontend.xml')) {
          try {
            junit allowEmptyResults: true, testResults: 'build/junit-backend.xml,build/junit-frontend.xml'
          } catch (Throwable err) {
            echo "junit step unavailable: ${err.class.simpleName}"
          }
        }
      }
      archiveArtifacts artifacts: 'build/**', allowEmptyArchive: true, fingerprint: true
    }
  }
}
