pipeline {
  agent {
    kubernetes {
      label 'lesavka-tests-disk'
      defaultContainer 'rust-ci'
      workspaceVolume dynamicPVC(accessModes: 'ReadWriteOnce', requestsSize: '40Gi', storageClassName: 'longhorn')
      yaml """
apiVersion: v1
kind: Pod
spec:
  securityContext:
    fsGroup: 1000
    fsGroupChangePolicy: OnRootMismatch
  nodeSelector:
    hardware: rpi5
    kubernetes.io/arch: arm64
    node-role.kubernetes.io/worker: "true"
  containers:
    - name: rust-ci
      image: registry.bstein.dev/bstein/lesavka-ci@sha256:db682677e608ca029c0291ea1475ddefd40c5d17897306403278b4266908d0e6
      command: ["cat"]
      tty: true
      env:
        - name: CARGO_HOME
          value: /home/jenkins/agent/.cargo-home
        - name: CARGO_TARGET_DIR
          value: /home/jenkins/agent/workspace/lesavka/target
      resources:
        requests:
          cpu: "250m"
          memory: "1024Mi"
          ephemeral-storage: "4Gi"
        limits:
          memory: "6Gi"
          ephemeral-storage: "8Gi"
      volumeMounts:
        - name: workspace-volume
          mountPath: /home/jenkins/agent
"""
    }
  }

  options {
    disableConcurrentBuilds()
    disableResume()
  }

  parameters {
    booleanParam(name: 'PUSH_IMAGES', defaultValue: false, description: 'Push images to registry (enable for release runs)')
    choice(name: 'LESAVKA_CI_PROFILE', choices: ['safe', 'daily', 'lab'], description: 'Safe is the normal non-disruptive gate; daily is intended for scheduled master/main runs; lab enables explicitly configured bare-metal probes.')
    booleanParam(name: 'RUN_DISRUPTIVE_INPUT_TESTS', defaultValue: false, description: 'Run virtual HID tests only on an isolated worker/session; these can emit keyboard/mouse events.')
    booleanParam(name: 'RUN_LAB_HARDWARE_GATES', defaultValue: false, description: 'Run opt-in bare-metal lab gates for Theia/Tethys/RCT probes when the Jenkins worker is prepared for them.')
    booleanParam(name: 'ENFORCE_COVERAGE_GATE', defaultValue: false, description: 'Fail CI when coverage is below the ratchet target; keep off while Lesavka is onboarding to the shared dashboard.')
    string(name: 'QUALITY_GATE_PUSHGATEWAY_URL', defaultValue: 'http://platform-quality-gateway.monitoring.svc.cluster.local:9091', description: 'Pushgateway base URL for quality gate metrics')
    string(name: 'REGISTRY_CREDENTIALS_ID', defaultValue: 'registry-bstein-dev', description: 'Jenkins credentials id for registry.bstein.dev')
  }

  environment {
    REGISTRY = 'registry.bstein.dev'
    IMAGE_PREFIX = "${REGISTRY}/lesavka"
    CARGO_TERM_COLOR = 'always'
    CARGO_BUILD_JOBS = '2'
    CARGO_INCREMENTAL = '0'
    CARGO_HOME = '/home/jenkins/agent/.cargo-home'
    CARGO_TARGET_DIR = "${WORKSPACE}/target"
    PATH = "/home/jenkins/agent/.cargo-home/bin:/usr/local/cargo/bin:${PATH}"
    DOCKER_BUILDKIT = '1'
    LESAVKA_CI_PROFILE = "${params.LESAVKA_CI_PROFILE}"
    LESAVKA_COVERAGE_ENFORCE = "${params.ENFORCE_COVERAGE_GATE}"
    QUALITY_GATE_PUSHGATEWAY_URL = "${params.QUALITY_GATE_PUSHGATEWAY_URL}"
  }

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

    stage('Bootstrap CI Toolchain') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          sh '''
            set -eu
            git config --global --add safe.directory "$WORKSPACE"
          '''
        }
      }
    }

    stage('Safe Gate (Single Exec)') {
      when {
        expression { return params.LESAVKA_CI_PROFILE == 'safe' }
      }
      steps {
        container('rust-ci') {
          sh '''
            set -eu

            git config --global --add safe.directory "$WORKSPACE"

            overall_rc=0
            run_gate() {
              name="$1"
              shift
              printf '\\n== %s ==\\n' "$name"
              if "$@"; then
                return 0
              else
                rc=$?
                printf 'gate failed: %s (rc=%s)\\n' "$name" "$rc" >&2
                overall_rc=1
              fi
            }

            export QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}"
            run_gate "style/docs/loc/naming" scripts/ci/hygiene_gate.sh
            run_gate "tests" scripts/ci/test_gate.sh

            if ! cargo llvm-cov --version >/dev/null 2>&1; then
              if ! cargo install --locked cargo-llvm-cov; then
                overall_rc=1
              fi
            fi
            run_gate "coverage" scripts/ci/quality_gate.sh
            run_gate "performance" scripts/ci/performance_gate.sh
            run_gate "media reliability" scripts/ci/media_reliability_gate.sh

            if [ "${RUN_DISRUPTIVE_INPUT_TESTS}" = "true" ]; then
              run_gate "input transport" env LESAVKA_ALLOW_DISRUPTIVE_INPUT_TESTS=1 scripts/ci/input_transport_gate.sh
            fi

            if [ "${RUN_LAB_HARDWARE_GATES}" = "true" ] || [ "${LESAVKA_CI_PROFILE}" = "lab" ]; then
              run_gate "bare-metal lab" env LESAVKA_ALLOW_LAB_HARDWARE_TESTS=1 scripts/ci/baremetal_lab_gate.sh
            fi

            run_gate "gate glue" scripts/ci/gate_glue_gate.sh
            run_gate "sonarqube" scripts/ci/sonarqube_gate.sh
            run_gate "build dist" scripts/ci/build-dist.sh
            run_gate "supply chain" scripts/ci/supply_chain_gate.sh

            exit "$overall_rc"
          '''
        }
      }
    }

    stage('Daily Master Gate') {
      when {
        expression { return params.LESAVKA_CI_PROFILE == 'daily' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/daily_master_gate.sh'
          }
        }
      }
    }

    stage('Style Docs LOC Naming') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/hygiene_gate.sh'
          }
        }
      }
    }

    stage('Tests') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/test_gate.sh'
          }
        }
      }
    }

    stage('Coverage') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh '''
              set -eu
              if ! cargo llvm-cov --version >/dev/null 2>&1; then
                cargo install --locked cargo-llvm-cov
              fi
              QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/quality_gate.sh
            '''
          }
        }
      }
    }

    stage('Performance') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/performance_gate.sh'
          }
        }
      }
    }

    stage('Media Reliability') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/media_reliability_gate.sh'
          }
        }
      }
    }

    stage('Input Transport (Isolated Opt-In)') {
      when {
        expression { return params.RUN_DISRUPTIVE_INPUT_TESTS && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" LESAVKA_ALLOW_DISRUPTIVE_INPUT_TESTS=1 scripts/ci/input_transport_gate.sh'
          }
        }
      }
    }

    stage('Bare-Metal Lab Gates (Opt-In)') {
      when {
        expression { return (params.RUN_LAB_HARDWARE_GATES || params.LESAVKA_CI_PROFILE == 'lab') && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" LESAVKA_ALLOW_LAB_HARDWARE_TESTS=1 scripts/ci/baremetal_lab_gate.sh'
          }
        }
      }
    }

    stage('Gate Glue') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/gate_glue_gate.sh'
          }
        }
      }
    }

    stage('SonarQube') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/sonarqube_gate.sh'
          }
        }
      }
    }

    stage('Build Dist') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'scripts/ci/build-dist.sh'
          }
        }
      }
    }

    stage('Supply Chain Artifact Security') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.LESAVKA_CI_PROFILE != 'safe' }
      }
      steps {
        container('rust-ci') {
          catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
            sh 'QUALITY_GATE_PUSHGATEWAY_URL="${QUALITY_GATE_PUSHGATEWAY_URL}" scripts/ci/supply_chain_gate.sh'
          }
        }
      }
    }

    stage('Docker Login') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.PUSH_IMAGES }
      }
      steps {
        withCredentials([
          usernamePassword(
            credentialsId: params.REGISTRY_CREDENTIALS_ID,
            usernameVariable: 'REGISTRY_USER',
            passwordVariable: 'REGISTRY_PASS'
          )
        ]) {
          sh 'echo "$REGISTRY_PASS" | docker login "$REGISTRY" -u "$REGISTRY_USER" --password-stdin'
        }
      }
    }

    stage('Build Images') {
      when {
        expression { return params.LESAVKA_CI_PROFILE != 'daily' && params.PUSH_IMAGES }
      }
      steps {
        sh 'PUSH_IMAGES=${PUSH_IMAGES} scripts/ci/build-images.sh'
      }
    }
  }

  post {
    always {
      script {
        try {
          archiveArtifacts artifacts: 'dist/**,target/test-gate/**,target/quality-gate/**,target/hygiene-gate/**,target/daily-master-gate/**,target/performance-gate/**,target/media-reliability-gate/**,target/input-transport-gate/**,target/baremetal-lab-gate/**,target/video-downstream-gate/**,target/gate-glue-gate/**,target/sonarqube-gate/**,target/supply-chain-gate/**', fingerprint: true, allowEmptyArchive: true
        } catch (Throwable err) {
          echo "archive step unavailable: ${err.class.simpleName}"
        }
      }
    }
  }
}
