name: Test and clippy zkVM

on:
  workflow_call:
    inputs:
      zkvm:
        description: 'zkVM to test'
        required: true
        type: string
      toolchain:
        description: 'Rust toolchain to use'
        required: false
        type: string
        default: 1.86.0
      test_ere_dockerized:
        description: 'Whether test ere-dockerized with the selected zkVM or not'
        required: false
        type: boolean
        default: true
      # Remove when we use larger runners, currently only needed to skip some zisk test
      test_options:
        description: 'Cargo test options when testing via Docker'
        required: false
        type: string
        default: ''

env:
  CARGO_TERM_COLOR: always

jobs:
  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ inputs.toolchain }}
          components: clippy

      - name: Run cargo clippy for ere-${{ inputs.zkvm }}
        run: |
          cargo clippy --all-targets \
            --package ere-${{ inputs.zkvm }} \
            -- -D warnings

      - name: Run cargo clippy for ere-cli with feature ${{ inputs.zkvm }}
        run: |
          cargo clippy --all-targets \
            --package ere-cli \
            --features cli,${{ inputs.zkvm }} \
            -- -D warnings

  build_image:
    name: Build image
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    outputs:
      image_version: ${{ steps.inspect_image.outputs.image_version }}
      base_image_tag: ${{ steps.inspect_image.outputs.base_image_tag }}
      base_zkvm_image_tag: ${{ steps.inspect_image.outputs.base_zkvm_image_tag }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Get image version and tags of ere-base and ere-base-${{ inputs.zkvm }}
        id: inspect_image
        run: |
          ZKVM_CRATE_VERSION=$(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.name == "ere-${{ inputs.zkvm }}") | .version')
          GIT_REV=$(git rev-parse --short=7 HEAD)
          IMAGE_VERSION="$ZKVM_CRATE_VERSION-$GIT_REV"
          BASE_IMAGE_TAG="ghcr.io/${{ github.repository }}/ere-base:$IMAGE_VERSION"
          BASE_ZKVM_IMAGE_TAG="ghcr.io/${{ github.repository }}/ere-base-${{ inputs.zkvm }}:$IMAGE_VERSION"

          echo "image_version=$IMAGE_VERSION" >> $GITHUB_OUTPUT
          echo "base_image_tag=$BASE_IMAGE_TAG" >> $GITHUB_OUTPUT
          echo "base_zkvm_image_tag=$BASE_ZKVM_IMAGE_TAG" >> $GITHUB_OUTPUT

      - name: Build ere-base image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: docker/base/Dockerfile.base
          push: true
          tags: ${{ steps.inspect_image.outputs.base_image_tag }}

      - name: Build ere-base-${{ inputs.zkvm }} image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: docker/${{ inputs.zkvm }}/Dockerfile
          push: true
          tags: ${{ steps.inspect_image.outputs.base_zkvm_image_tag }}
          build-args: |
            CI=1
            BASE_IMAGE_TAG=${{ steps.inspect_image.outputs.base_image_tag }}

  test_via_docker:
    name: Test via Docker
    needs: build_image
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Pull image ere-base-${{ inputs.zkvm }}
        run: docker image pull ${{ needs.build_image.outputs.base_zkvm_image_tag }}

      - name: Run cargo test for ere-${{ inputs.zkvm }} via Docker
        run: |
          docker run \
            --rm \
            --volume ${{ github.workspace }}:/ere \
            --workdir /ere \
            ${{ needs.build_image.outputs.base_zkvm_image_tag }} \
            /bin/sh -c "\$(RUSTFLAGS=-Ctarget-cpu=native cargo test --release --package ere-${{ inputs.zkvm }} --no-run --message-format json \
              | jq -r 'select(.executable) | select(.package_id | contains(\"ere-${{ inputs.zkvm }}\")) | .executable') \
              ${{ inputs.test_options }}"

  test_ere_dockerized:
    name: Test ere-dockerized with the selected zkVM
    if: ${{ inputs.test_ere_dockerized }}
    needs: build_image
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ inputs.toolchain }}

      - name: Cache dependencies
        uses: Swatinem/rust-cache@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Pull image ere-base and ere-base-${{ inputs.zkvm }}
        run: |
          docker image pull ${{ needs.build_image.outputs.base_image_tag }}
          docker image pull ${{ needs.build_image.outputs.base_zkvm_image_tag }}
          docker image tag ${{ needs.build_image.outputs.base_image_tag }} ere-base:${{ needs.build_image.outputs.image_version }}
          docker image tag ${{ needs.build_image.outputs.base_zkvm_image_tag }} ere-base-${{ inputs.zkvm }}:${{ needs.build_image.outputs.image_version }}

      - name: Run cargo test for ere-${{ inputs.zkvm }} via ere-dockerized
        run: cargo test --release --package ere-dockerized -- ${{ inputs.zkvm }}
