# This workflow will check code style of the project files (mostly Java).
#
# By design, it is expected to only analyse files affected by given
# pull request, and not the whole source tree.
#
# Marcin Orlowski

name: "Code style"
on:
  push:
    # main is left just for emergency cases.
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  analyze_sources:
    name: "Is there any Java source code to lint?"
    runs-on: ubuntu-latest

    outputs:
      # Export 'filter' step check result so next step can use it.
      run_checkstyle: ${{ steps.filter.outputs.src }}
      # These are source files matching our filter that are affected by the PR.
      changed_files: ${{ steps.filter.outputs.src_files }}

    steps:
    - name: "Install packages..."
      run: sudo apt-get install -y sysvbanner

      # https://github.com/marketplace/actions/checkout
    - name: "Checkout sources"
      uses: actions/checkout@v6

      # https://github.com/marketplace/actions/paths-changes-filter
    - name: "Look for changes that matters for us..."
      uses: dorny/paths-filter@v3
      id: filter
      with:
        list-files: 'escape'
        filters: |
          src:
            - 'src/**/*.java'

    - name: "WILL JAVA LINT STEP BE RUN?"
      run: |
        found="NO"
        [[ ${{ steps.filter.outputs.src }} == 'true' ]] && found="YES"
        echo "run_checkstyle=${found}" >> $GITHUB_OUTPUT
        echo -e "\n****************************************\n"
        banner "${found}"
        echo -e "****************************************"

  # Build step.
  checkstyle:
    name: "Code style linter"
    runs-on: ubuntu-latest

    # Will run only if analyze_sources determined it is needed.
    needs: analyze_sources
    if: needs.analyze_sources.outputs.run_checkstyle == 'true'

    # TODO: we may want to use checkstyle.jar directly, skipping cli wrapper
    # that would let us use most recent version, but would also require downloading
    # such instead of installing packaged version via apt.

    steps:
    - name: "Checkout sources"
      uses: actions/checkout@v6

    - name: "Lint changed files"
      run: |
        # Run CheckStyle
        # https://github.com/checkstyle/checkstyle/releases/
        CHECKSTYLE_VERSION="10.3.4"
        JAR="checkstyle-${CHECKSTYLE_VERSION}-all.jar"
        URL="https://github.com/checkstyle/checkstyle/releases/download/checkstyle-${CHECKSTYLE_VERSION}/${JAR}"

        echo "Downloading ${JAR}..."
        wget --quiet "${URL}"

        # Using built-in config.
        declare -r CHECKS_FILE="/google_checks.xml"
        declare -r REPORT_FILE="output.txt"

        # Let's lint eventually...
        echo "*********************************************************"
        java -version
        echo "Linting using $(java -jar "${JAR}" --version)"
        java -jar "${JAR}" -o "${REPORT_FILE}" -c "${CHECKS_FILE}" ${{ needs.analyze_sources.outputs.changed_files }}

        # Plain output always contains "Starting audit..." and "Audit done." lines. Let's remove them.
        sed -i 's/^Starting audit...$//; s/^Audit done.$//' "${REPORT_FILE}"

        # The `strings` tool is used to filter out empty lines.
        cnt="$(strings "${REPORT_FILE}" | wc -l)"
        if [[ "${cnt}" -gt 0 ]]; then
          echo "*********************************************************"
          echo "* FIXME! Code style guide violations detected: ${cnt}"
          echo "*"
          echo "* For more information about used code style guide see:"
          echo "* https://github.com/logisim-evolution/logisim-evolution/blob/main/docs/style.md"
          echo "*********************************************************"
          cat "${REPORT_FILE}"
          exit 1
        else
          echo "Looks good. No style guide violations found."
        fi
