# Security Diff for Merge Requests (GitLab CI)
#
# This job automatically compares security findings between the target branch
# and the MR branch, posting results as an MR comment and enforcing security gates.
#
# Add this to your .gitlab-ci.yml file:

# Example integration:
# include:
#   - local: 'docs/examples/gitlab-ci-diff.yml'

# Or copy the job below directly into your .gitlab-ci.yml

security-diff:
  stage: test
  image: python:3.11-slim
  timeout: 30m

  # Only run on merge requests
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

  variables:
    PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
    BASELINE_DIR: "baseline-results"
    CURRENT_DIR: "current-results"

  cache:
    paths:
      - .cache/pip
      - venv/

  before_script:
    # Install system dependencies
    - apt-get update && apt-get install -y git curl jq

    # Set up Python environment
    - python -m venv venv
    - source venv/bin/activate
    - pip install --upgrade pip
    - pip install jmo-security

  script:
    # ========================================================================
    # Step 1: Scan baseline (target branch)
    # ========================================================================
    - echo "📊 Scanning baseline ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME)..."
    - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
    - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
    - jmo scan --repo . --profile fast --results-dir $BASELINE_DIR/
    - echo "✅ Baseline scan complete"

    # ========================================================================
    # Step 2: Scan current (MR branch)
    # ========================================================================
    - echo "📊 Scanning current ($CI_COMMIT_REF_NAME)..."
    - git checkout $CI_COMMIT_REF_NAME
    - jmo scan --repo . --profile fast --results-dir $CURRENT_DIR/
    - echo "✅ Current scan complete"

    # ========================================================================
    # Step 3: Generate diff reports
    # ========================================================================
    - echo "🔍 Generating diff reports..."

    # Markdown report for MR comment
    - jmo diff $BASELINE_DIR/ $CURRENT_DIR/
        --format md
        --output diff.md
        --severity CRITICAL,HIGH,MEDIUM

    # JSON report for gating
    - jmo diff $BASELINE_DIR/ $CURRENT_DIR/
        --format json
        --output diff.json

    # HTML report for artifact download
    - jmo diff $BASELINE_DIR/ $CURRENT_DIR/
        --format html
        --output diff-report.html

    # ========================================================================
    # Step 4: Post MR comment
    # ========================================================================
    - |
      echo "💬 Posting MR comment..."

      # Read diff content
      DIFF_CONTENT=$(cat diff.md)

      # Prepare JSON payload (escape newlines and quotes)
      COMMENT_BODY=$(jq -Rs . <<< "$DIFF_CONTENT")

      # Post comment using GitLab API
      curl --request POST \
        --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" \
        --header "Content-Type: application/json" \
        --data "{\"body\": $COMMENT_BODY}" \
        "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"

      echo "✅ MR comment posted"

    # ========================================================================
    # Step 5: Extract statistics for gating
    # ========================================================================
    - |
      echo "📊 Extracting statistics..."

      CRITICAL=$(jq -r '.statistics.new_by_severity.CRITICAL // 0' diff.json)
      HIGH=$(jq -r '.statistics.new_by_severity.HIGH // 0' diff.json)
      MEDIUM=$(jq -r '.statistics.new_by_severity.MEDIUM // 0' diff.json)
      TOTAL_NEW=$(jq -r '.statistics.total_new' diff.json)
      TOTAL_RESOLVED=$(jq -r '.statistics.total_resolved' diff.json)
      TREND=$(jq -r '.statistics.trend' diff.json)

      echo "🆕 New findings:"
      echo "  - CRITICAL: $CRITICAL"
      echo "  - HIGH: $HIGH"
      echo "  - MEDIUM: $MEDIUM"
      echo "  - TOTAL: $TOTAL_NEW"
      echo ""
      echo "✅ Resolved: $TOTAL_RESOLVED"
      echo "📈 Trend: $TREND"

    # ========================================================================
    # Step 6: Security gate (fail on new CRITICAL/HIGH)
    # ========================================================================
    - |
      echo "🚦 Applying security gate..."

      CRITICAL=$(jq -r '.statistics.new_by_severity.CRITICAL // 0' diff.json)
      HIGH=$(jq -r '.statistics.new_by_severity.HIGH // 0' diff.json)
      GATE_TOTAL=$((CRITICAL + HIGH))

      if [ "$GATE_TOTAL" -gt 0 ]; then
        echo "❌ FAILED: Found $GATE_TOTAL new CRITICAL/HIGH findings"
        echo "::error::Security gate failed: $GATE_TOTAL new CRITICAL/HIGH findings detected"
        exit 1
      else
        echo "✅ PASSED: No new CRITICAL/HIGH findings"
      fi

  artifacts:
    when: always
    expire_in: 30 days
    paths:
      - diff.md
      - diff.json
      - diff-report.html
      - $BASELINE_DIR/summaries/
      - $CURRENT_DIR/summaries/
    reports:
      # Optional: Generate test report from findings
      junit: diff.json

  # Allow failure for informational runs (optional)
  # allow_failure: false

# ============================================================================
# Alternative: Informational mode (no gating)
# ============================================================================

security-diff-informational:
  extends: security-diff
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $SECURITY_GATE_ENABLED != "true"
  allow_failure: true
  before_script:
    # Reuse same setup
    - apt-get update && apt-get install -y git curl jq
    - python -m venv venv
    - source venv/bin/activate
    - pip install --upgrade pip
    - pip install jmo-security
  script:
    # Reuse main job script but override gating
    - echo "📊 Scanning baseline ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME)..."
    - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
    - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
    - jmo scan --repo . --profile fast --results-dir $BASELINE_DIR/
    - echo "✅ Baseline scan complete"
    - echo "📊 Scanning current ($CI_COMMIT_REF_NAME)..."
    - git checkout $CI_COMMIT_REF_NAME
    - jmo scan --repo . --profile fast --results-dir $CURRENT_DIR/
    - jmo diff $BASELINE_DIR/ $CURRENT_DIR/ --format md --output diff.md --severity CRITICAL,HIGH,MEDIUM
    - jmo diff $BASELINE_DIR/ $CURRENT_DIR/ --format json --output diff.json
    # Informational only - no gating
    - |
      echo "ℹ️ Informational mode: No gating applied"
      CRITICAL=$(jq -r '.statistics.new_by_severity.CRITICAL // 0' diff.json)
      HIGH=$(jq -r '.statistics.new_by_severity.HIGH // 0' diff.json)
      echo "📊 Found $CRITICAL CRITICAL and $HIGH HIGH findings (informational only)"

# ============================================================================
# Advanced: Scheduled full scan comparison
# ============================================================================

security-diff-weekly:
  extends: security-diff
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
  variables:
    BASELINE_DIR: "scan-last-week"
    CURRENT_DIR: "scan-current-week"
  script:
    # Compare last week's scan to current week
    - echo "📊 Weekly security posture comparison..."
    - git checkout main
    - jmo scan --repo . --profile balanced --results-dir $CURRENT_DIR/

    # Download last week's results from artifacts or storage
    - curl -o scan-last-week.tar.gz "$LAST_WEEK_SCAN_URL"
    - tar -xzf scan-last-week.tar.gz -C $BASELINE_DIR/

    # Generate comparison
    - jmo diff $BASELINE_DIR/ $CURRENT_DIR/
        --format md
        --output weekly-diff.md

    # Post to Slack/Teams/etc. (add your integration)
    - echo "📤 Posting to team chat..."
    # curl -X POST $SLACK_WEBHOOK_URL -d @weekly-diff.md
