# GitLab CI Pipeline for PMAT TDG Quality Enforcement
# Auto-generated by `pmat hooks install --tdg-enforcement --ci gitlab`
# DO NOT EDIT MANUALLY - Regenerate with `pmat hooks refresh`
#
# This pipeline enforces quality gates on merge requests and commits:
# - Runs TDG analysis on all code changes
# - Checks for quality regressions against baseline
# - Enforces minimum quality grades for new/modified files
# - Blocks merges that violate configured thresholds
# - Auto-updates baseline on main branch commits
#
# Configuration: .pmat/tdg-rules.toml

variables:
  PMAT_VERSION: "{{PMAT_VERSION}}"
  BASELINE_PATH: "{{BASELINE_PATH}}"
  MIN_GRADE: "{{MIN_GRADE}}"
  MAX_SCORE_DROP: "{{MAX_SCORE_DROP}}"
  MODE: "{{MODE}}"
  CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
  GIT_DEPTH: "0"  # Full history for git context

stages:
  - install
  - analyze
  - report
  - update

# Cache cargo dependencies across jobs
.cache_template: &cargo_cache
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .cargo/
      - target/

# Install PMAT
install_pmat:
  stage: install
  image: rust:latest
  <<: *cargo_cache
  script:
    - echo "📦 Installing PMAT v${PMAT_VERSION}..."
    - cargo install pmat --version ${PMAT_VERSION} --force
    - pmat --version
    - mkdir -p .pmat-bin
    - cp ~/.cargo/bin/pmat .pmat-bin/
  artifacts:
    paths:
      - .pmat-bin/pmat
    expire_in: 1 hour

# Check or create baseline
baseline_check:
  stage: install
  image: rust:latest
  dependencies:
    - install_pmat
  script:
    - cp .pmat-bin/pmat /usr/local/bin/pmat
    - |
      if [ -f "${BASELINE_PATH}" ]; then
        echo "✅ Found existing baseline: ${BASELINE_PATH}"
      else
        echo "⚠️  No baseline found, creating initial baseline..."
        mkdir -p $(dirname "${BASELINE_PATH}")
        pmat tdg baseline create --output "${BASELINE_PATH}" --path .
        echo "✅ Initial baseline created"
      fi
  artifacts:
    paths:
      - ${BASELINE_PATH}
    expire_in: 1 hour

# Run regression check on merge requests
tdg_regression_check:
  stage: analyze
  image: rust:latest
  dependencies:
    - install_pmat
    - baseline_check
  only:
    - merge_requests
  script:
    - cp .pmat-bin/pmat /usr/local/bin/pmat
    - echo "🔍 Checking for quality regressions..."
    - |
      pmat tdg check-regression \
        --baseline "${BASELINE_PATH}" \
        --path . \
        --format table \
        --max-score-drop ${MAX_SCORE_DROP} \
        --fail-on-regression || REGRESSION_FAILED=1

      if [ "${MODE}" = "warning" ] && [ "${REGRESSION_FAILED}" = "1" ]; then
        echo "⚠️  Quality regression detected (warning mode)"
        exit 0
      elif [ "${REGRESSION_FAILED}" = "1" ]; then
        echo "❌ Quality regression detected - blocking merge"
        exit 1
      else
        echo "✅ No quality regressions detected"
      fi
  allow_failure: false

# Check quality of new/modified files
tdg_quality_check:
  stage: analyze
  image: rust:latest
  dependencies:
    - install_pmat
    - baseline_check
  only:
    - merge_requests
  script:
    - cp .pmat-bin/pmat /usr/local/bin/pmat
    - echo "📋 Checking quality of new/modified files..."
    - |
      pmat tdg check-quality \
        --path . \
        --format table \
        --new-files-only \
        --baseline "${BASELINE_PATH}" \
        --min-grade ${MIN_GRADE} \
        --fail-on-violation || QUALITY_FAILED=1

      if [ "${MODE}" = "warning" ] && [ "${QUALITY_FAILED}" = "1" ]; then
        echo "⚠️  Quality violations detected (warning mode)"
        exit 0
      elif [ "${QUALITY_FAILED}" = "1" ]; then
        echo "❌ Quality violations detected - blocking merge"
        exit 1
      else
        echo "✅ All files meet quality standards"
      fi
  allow_failure: false

# Generate comprehensive TDG report
tdg_report:
  stage: report
  image: rust:latest
  dependencies:
    - install_pmat
    - baseline_check
  script:
    - cp .pmat-bin/pmat /usr/local/bin/pmat
    - echo "📊 Generating comprehensive TDG report..."
    - pmat tdg --path . --format json --output tdg-report.json
    - pmat tdg --path . --format markdown --output tdg-report.md
    - |
      echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
      echo "📊 PMAT TDG Quality Report Summary"
      echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
      cat tdg-report.md
  artifacts:
    reports:
      junit: tdg-report.xml
    paths:
      - tdg-report.json
      - tdg-report.md
    expire_in: 30 days
  allow_failure: true

# Update baseline on main branch commits
tdg_baseline_update:
  stage: update
  image: rust:latest
  dependencies:
    - install_pmat
    - baseline_check
  only:
    - main
    - master
  script:
    - cp .pmat-bin/pmat /usr/local/bin/pmat
    - echo "📊 Updating baseline for main branch..."
    - pmat tdg baseline update --output "${BASELINE_PATH}" --path .
    - |
      # Configure git
      git config user.name "gitlab-ci"
      git config user.email "gitlab-ci@${CI_PROJECT_NAME}"

      # Commit and push updated baseline if changed
      if ! git diff --quiet "${BASELINE_PATH}"; then
        git add "${BASELINE_PATH}"
        git commit -m "chore: Update TDG baseline [skip ci]

        Auto-updated by PMAT TDG enforcement pipeline

        🤖 Generated with PMAT"

        # Push using GitLab CI token
        git push "https://oauth2:${CI_JOB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" HEAD:${CI_COMMIT_REF_NAME}

        echo "✅ Baseline updated and committed"
      else
        echo "ℹ️  Baseline unchanged"
      fi
  allow_failure: true

# Display final summary
tdg_summary:
  stage: .post
  image: rust:latest
  script:
    - |
      echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
      echo "📊 PMAT TDG Quality Enforcement Summary"
      echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
      echo "Pipeline: ${CI_PIPELINE_ID}"
      echo "Commit: ${CI_COMMIT_SHORT_SHA}"
      echo "Branch: ${CI_COMMIT_REF_NAME}"
      echo "Baseline: ${BASELINE_PATH}"
      echo "Min Grade: ${MIN_GRADE}"
      echo "Max Score Drop: ${MAX_SCORE_DROP}"
      echo "Mode: ${MODE}"
      echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  allow_failure: true
  when: always
