name: SonarCloud Analysis

on:
  workflow_run:
    workflows: ["CI"]
    types:
      - completed
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  # Do NOT cancel in-progress runs: cancelling a mid-flight SonarCloud analysis
  # leaves the quality gate in a permanent 'pending' state for the triggering CI run.
  cancel-in-progress: false

permissions:
  contents: read

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
  PYTHON_VERSION: "3.13"
  POETRY_VERSION: "2.3.4"

jobs:
  sonarcloud:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    # Only run if CI workflow succeeded and not from a fork (security: prevent untrusted code execution with secrets)
    if: |
      (github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch') &&
      (github.event_name == 'workflow_dispatch' || github.event.workflow_run.head_repository.full_name == github.repository)

    steps:
    - name: Check for SONAR_TOKEN secret
      id: check-token
      env:
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
      run: |
        if [ -z "$SONAR_TOKEN" ]; then
          echo "SONAR_TOKEN is not set. Skipping SonarCloud analysis."
          echo "has_token=false" >> $GITHUB_OUTPUT
        else
          echo "has_token=true" >> $GITHUB_OUTPUT
        fi

    - name: Checkout repository
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      if: steps.check-token.outputs.has_token == 'true'
      with:
        # For security: always checkout repository code, never code from forks
        # The workflow_run event provides coverage data via artifacts
        fetch-depth: 0  # Shallow clones should be disabled for better analysis

    - name: Set up Python ${{ env.PYTHON_VERSION }}
      if: steps.check-token.outputs.has_token == 'true'
      uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Set up Go
      if: steps.check-token.outputs.has_token == 'true'
      uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v5
      with:
        go-version-file: 'go.work'
        cache-dependency-path: terraform-provider/go.sum

    - name: Install Poetry
      if: steps.check-token.outputs.has_token == 'true'
      uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1
      with:
        version: ${{ env.POETRY_VERSION }}
        virtualenvs-create: true
        virtualenvs-in-project: true

    - name: Cache Poetry dependencies
      if: steps.check-token.outputs.has_token == 'true'
      uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
      with:
        path: .venv
        key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
        restore-keys: |
          ${{ runner.os }}-poetry-

    - name: Install dependencies
      if: steps.check-token.outputs.has_token == 'true'
      # --no-root: skip building/installing the project root to prevent execution
      # of setup scripts on source builds (SonarLint S8541).
      run: poetry install --no-interaction --no-root --all-extras

    - name: Generate coverage for SonarCloud (workflow_dispatch only)
      # On workflow_run, coverage is taken from the CI run's uploaded artifact to
      # ensure SonarCloud reports the same numbers that CI measured.
      if: steps.check-token.outputs.has_token == 'true' && github.event_name == 'workflow_dispatch'
      run: |
        poetry run pytest --cov=souschef --cov-report=xml --cov-report=term-missing
        echo "Python coverage generated:"
        ls -lh coverage.xml

    - name: Download coverage artifacts from CI workflow
      if: steps.check-token.outputs.has_token == 'true' && github.event_name == 'workflow_run'
      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v4
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        run-id: ${{ github.event.workflow_run.id }}
        path: coverage-artifacts

    - name: Prepare coverage files
      if: steps.check-token.outputs.has_token == 'true' && github.event_name == 'workflow_run'
      run: |
        set -e
        echo "Checking for coverage artifacts..."
        ls -lh coverage-artifacts/ 2>/dev/null || echo "No coverage-artifacts directory found"

        # Python coverage: reuse what CI measured (artifact name: python-coverage).
        PYTHON_COV=$(find coverage-artifacts -type f -name "coverage.xml" | head -n 1 || true)
        if [ -n "$PYTHON_COV" ] && [ -f "$PYTHON_COV" ]; then
          echo "Found Python coverage at $PYTHON_COV"
          cp "$PYTHON_COV" coverage.xml
          echo "✓ Python coverage copied to coverage.xml"
          ls -lh coverage.xml
        else
          echo "⚠ Python coverage not found in artifacts — regenerating"
          poetry run pytest --cov=souschef --cov-report=xml --cov-report=term-missing
        fi

        # Go coverage: artifact name is go-coverage.
        GO_COV=$(find coverage-artifacts -type f -name "coverage.out" | head -n 1 || true)
        if [ -n "$GO_COV" ] && [ -f "$GO_COV" ]; then
          echo "Found Go coverage at $GO_COV"
          mkdir -p terraform-provider
          cp "$GO_COV" terraform-provider/coverage.out
          echo "✓ Go coverage copied to terraform-provider/coverage.out"
          ls -lh terraform-provider/coverage.out
        else
          echo "⚠ Go coverage not found in downloaded artifacts"
          find coverage-artifacts -type f 2>/dev/null || echo "No files in coverage-artifacts"
        fi

        # Final verification
        echo ""
        echo "Coverage files ready for SonarCloud:"
        ls -lh coverage.xml 2>/dev/null || echo "  - Python coverage: MISSING"
        ls -lh terraform-provider/coverage.out 2>/dev/null || echo "  - Go coverage: MISSING"

    - name: Run SonarCloud analysis
      if: steps.check-token.outputs.has_token == 'true'
      uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9 # v7.0.0
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
      # Configuration is in sonar-project.properties
      # Note: Disable "Automatic Analysis" in SonarCloud project settings
      # (Administration > Analysis Method) to avoid conflicts with CI analysis
