name: Build Tests

on: [push, pull_request]

jobs:
  wait-for-build:
    name: Waiting for build
    runs-on: ubuntu-latest
    steps:
      - name: Wait for build
        uses: lewagon/wait-on-check-action@v1.3.4
        with:
          ref: ${{ github.ref }}
          check-name: 'Building JSS'
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          wait-interval: 30
        if: github.event_name == 'push'

      - name: Wait for build
        uses: lewagon/wait-on-check-action@v1.3.4
        with:
          ref: ${{ github.event.pull_request.head.sha }}
          check-name: 'Building JSS'
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          wait-interval: 30
        if: github.event_name == 'pull_request'

  build-test:
    name: Build Test
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os:
          - 'debian:testing'
          - 'ubuntu:rolling'
    container: ${{ matrix.os }}
    steps:
    - name: Clone repository
      uses: actions/checkout@v4

    - name: Set up Java
      uses: actions/setup-java@v4
      with:
        java-version: '21'
        distribution: 'adopt'

    - name: Install dependencies
      run: |
        apt-get update

        # https://salsa.debian.org/freeipa-team/jss/-/blob/master/debian/control
        apt-get install -y \
            cmake \
            g++ \
            junit5 \
            libcommons-lang3-java \
            libnss3-dev \
            libnss3-tools \
            libopentest4j-java \
            libslf4j-java \
            maven \
            openjdk-21-jdk \
            unzip \
            zip

    - name: Build with CMake
      run: ./build.sh

    - name: Build with Maven
      run: mvn --batch-mode package

    - name: Compare jss.jar
      run: |
        jar tvf ~/build/jss/jss.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee cmake.out
        jar tvf base/target/jss.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | grep -v '^META-INF/maven/' \
            | tee maven.out
        diff cmake.out maven.out

    # TODO: Run examples

  fedora-test:
    name: Fedora Build Test
    needs: wait-for-build
    runs-on: ubuntu-latest
    env:
      SHARED: /tmp/workdir/jss
    steps:
    - name: Clone repository
      uses: actions/checkout@v4

    - name: Retrieve JSS images
      uses: actions/cache@v4
      with:
        key: jss-images-${{ github.sha }}
        path: jss-images.tar

    - name: Load JSS images
      run: docker load --input jss-images.tar

    - name: Set up JSS container
      run: |
        tests/bin/runner-init.sh \
            --image=jss-builder \
            --hostname=jss.example.com \
            jss

    - name: Build with CMake
      run: |
        docker exec jss ./build.sh --cmake='/usr/bin/cmake -DENABLE_NSS_VERSION_PQC_DEF=ON'

    - name: Build with Maven
      run: |
        docker exec jss mvn --batch-mode -pl '!native,!symkey,!examples' package

    - name: Compare jss.jar
      run: |
        docker exec jss \
            jar tvf /root/build/jss/jss.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee cmake.out
        docker exec jss \
            jar tvf base/target/jss.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | grep -v '^META-INF/maven/' \
            | tee maven.out
        diff cmake.out maven.out

    # TODO: Run examples

  # Compare JNI symbols in the code and in the version script.
  # If there are JNI symbols in the code but not in the version script -> fail.
  symbol-test:
    name: Symbol Test
    runs-on: ubuntu-latest
    env:
      JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Get JNI symbols in the code
        run: |
          grep -iroh '^Java_org_mozilla[^(;]*' native/src/main/native/ | sort -u > /tmp/functions.txt
          cat /tmp/functions.txt

      - name: Get JNI symbols in the version script
        run: |
          grep -iroh '^Java_org_mozilla[^(;]*' lib/ | sort -u > /tmp/version.txt
          cat /tmp/version.txt

      - name: Compare JNI symbols
        run: |
          diff /tmp/functions.txt /tmp/version.txt || true
          comm -23 --check-order /tmp/functions.txt /tmp/version.txt > /tmp/diff.txt
          test ! -s /tmp/diff.txt

  rpm-test:
    name: RPM Test
    needs: wait-for-build
    runs-on: ubuntu-latest
    env:
      SHARED: /tmp/workdir/jss
    steps:
    - name: Clone repository
      uses: actions/checkout@v4

    - name: Retrieve JSS images
      uses: actions/cache@v4
      with:
        key: jss-images-${{ github.sha }}
        path: jss-images.tar

    - name: Load jss-images image
      run: docker load --input jss-images.tar

    - name: Set up JSS container
      run: |
        tests/bin/runner-init.sh \
            --image=jss-builder \
            --hostname=jss.example.com \
            jss

          # get Fedora version
          FEDORA_VERSION=$(docker exec jss sed -n 's/^VERSION_ID=//p' /etc/os-release)
          echo "FEDORA_VERSION=$FEDORA_VERSION" >> $GITHUB_ENV

    - name: Install RPMs
      run: |
        docker exec jss bash -c "dnf install -y build/RPMS/*.rpm"

    - name: Build with Maven
      run: |
        docker exec jss mvn --batch-mode -pl '!native,!symkey,!examples' package

    - name: Compare jss.jar
      run: |
        docker exec jss jar tvf /usr/share/java/jss/jss.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee rpm.out
        docker exec jss jar tvf base/target/jss.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee maven.out
        diff rpm.out maven.out

    - name: Compare jss-tomcat.jar
      run: |
        docker exec jss jar tvf /usr/share/java/jss/jss-tomcat.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee rpm.out
        docker exec jss jar tvf tomcat/target/jss-tomcat.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee maven.out
        diff rpm.out maven.out

    - name: Compare jss-tomcat-9.0.jar
      if: ${{ fromJSON(env.FEDORA_VERSION) < 43 }}
      run: |
        docker exec jss jar tvf /usr/share/java/jss/jss-tomcat-9.0.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee rpm.out
        docker exec jss jar tvf tomcat-9.0/target/jss-tomcat-9.0.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee maven.out
        diff rpm.out maven.out

    - name: Compare jss-tomcat-10.1.jar
      if: ${{ fromJSON(env.FEDORA_VERSION) >= 43 }}
      run: |
        docker exec jss jar tvf /usr/share/java/jss/jss-tomcat-10.1.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee rpm.out
        docker exec jss jar tvf tomcat-10.1/target/jss-tomcat-10.1.jar \
            | awk '{print $8;}' \
            | sort \
            | grep -v '/$' \
            | tee maven.out
        diff rpm.out maven.out

    - name: Install RPMInspect
      run: |
        docker exec jss dnf copr enable -y copr.fedorainfracloud.org/dcantrell/rpminspect
        docker exec jss dnf install -y rpminspect rpminspect-data-fedora

    - name: Run RPMInspect on SRPM and RPMs
      run: |
        docker exec jss ./tests/bin/rpminspect.sh

  sandbox-test:
    name: Sandbox Test
    needs: wait-for-build
    runs-on: ubuntu-latest
    env:
      SHARED: /tmp/workdir/jss
    steps:
    - name: Clone repository
      uses: actions/checkout@v4

    - name: Retrieve JSS images
      uses: actions/cache@v4
      with:
        key: jss-images-${{ github.sha }}
        path: jss-images.tar

    - name: Load jss-images image
      run: docker load --input jss-images.tar

    - name: Set up JSS container
      run: |
        tests/bin/runner-init.sh \
            --image=jss-builder \
            --hostname=jss.example.com \
            jss

    - name: Install build dependencies
      run: |
        docker exec jss dnf builddep -y nspr nss
        docker exec jss dnf install -y mercurial \
            python-unversioned-command \
            gyp \
            ninja-build

    - name: Build NSPR and NSS
      run: |
        docker exec jss hg clone https://hg.mozilla.org/projects/nspr
        docker exec jss hg clone https://hg.mozilla.org/projects/nss
        docker exec -w /root/jss/nss jss \
            bash build.sh --enable-fips --enable-libpkix

    - name: Build JSS
      run: |
        docker exec -w /root/jss/build jss cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_NSS_VERSION_PQC_DEF=ON ..
        docker exec -w /root/jss/build jss make all
      env:
        SANDBOX: 1
        CFLAGS: -Wall -Wextra -Werror -Og -ggdb

    - name: Run JSS tests
      run: |
        docker exec -w /root/jss/build jss ctest --output-on-failure
