on:
  workflow_call:
    inputs:
      publish:
        default: false
        type: boolean
        required: true
      latest:
        default: false
        type: boolean
        required: true
      version:
        default: ${{ github.sha }}
        type: string
        required: true

jobs:
  detect-changes:
    runs-on: ubuntu-22.04
    outputs:
      rust_changed: ${{ steps.rust_changed.outputs.rust_changed }}

    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          fetch-depth: 2
      - name: Look for changes
        id: rust_changed
        run: |
          lines=$( git diff HEAD~ HEAD --name-only -- 'packages/libraries/router' 'packages/libraries/sdk-rs' 'Cargo.toml' 'configs/cargo/Cargo.lock' | wc -l )
          if [ $lines -gt 0 ]; then
              echo 'rust_changed=true' >> $GITHUB_OUTPUT
          fi

  test-rust:
    needs: detect-changes
    if: needs.detect-changes.outputs.rust_changed == 'true'
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          fetch-depth: 2

      - name: setup environment
        uses: ./.github/actions/setup
        with:
          actor: test-rust
          codegen: false

      - name: Install Protoc
        uses: arduino/setup-protoc@v3
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Install Rust
        uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1
        with:
          toolchain: '1.91.1'
          default: true
          override: true

      - name: Cache Rust
        uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2

      - name: Run tests
        run: cargo test

  publish-rust:
    needs: [detect-changes, test-rust]
    if: needs.detect-changes.outputs.rust_changed == 'true'
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    runs-on: ${{ matrix.os }}
    timeout-minutes: 60

    steps:
      - name: Checkout
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          fetch-depth: 2

      - name: setup environment
        uses: ./.github/actions/setup
        with:
          actor: publish-rust
          codegen: false

      - name: Prepare MacOS
        if: ${{ matrix.os == 'macos-latest' }}
        run: |
          echo "RUST_TARGET=x86_64-apple-darwin" >> $GITHUB_ENV
          echo "RUST_TARGET_FILE=router" >> $GITHUB_ENV
          echo "RUST_TARGET_OS=macos" >> $GITHUB_ENV

      - name: Prepare Linux
        if: ${{ matrix.os == 'ubuntu-latest' }}
        run: |
          echo "RUST_TARGET=x86_64-unknown-linux-gnu" >> $GITHUB_ENV
          echo "RUST_TARGET_FILE=router" >> $GITHUB_ENV
          echo "RUST_TARGET_OS=linux" >> $GITHUB_ENV

      - name: Prepare Windows
        if: ${{ matrix.os == 'windows-latest' }}
        run: |
          echo "RUST_TARGET=x86_64-pc-windows-msvc" | Out-File -FilePath $env:GITHUB_ENV -Append
          echo "RUST_TARGET_FILE=router.exe" | Out-File -FilePath $env:GITHUB_ENV -Append
          echo "RUST_TARGET_OS=win" | Out-File -FilePath $env:GITHUB_ENV -Append
          npm run cargo:fix

      - name: Install Protoc
        uses: arduino/setup-protoc@v3
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Install Rust
        uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1
        with:
          toolchain: '1.91.1'
          target: ${{ env.RUST_TARGET }}
          default: true
          override: true

      - name: Cache Rust
        uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2

      - name: Build
        uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1
        with:
          command: build
          args: --release

      - name: Strip binary from debug symbols
        if: ${{ matrix.os == 'ubuntu-latest' }}
        run: strip target/release/${{ env.RUST_TARGET_FILE }}

      - name: Compress
        run: |
          ./target/release/compress ./target/release/${{ env.RUST_TARGET_FILE }} ./router.tar.gz

      - name: Upload artifact
        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4
        with:
          name: router-${{ env.RUST_TARGET_OS }}
          path: router.tar.gz

      - name: Upload to R2 (${{ inputs.version }})
        if: ${{ inputs.publish }}
        uses: randomairborne/r2-release@9cbc35a2039ee2ef453a6988cd2a85bb2d7ba8af # v1.0.2
        with:
          endpoint: https://6d5bc18cd8d13babe7ed321adba3d8ae.r2.cloudflarestorage.com
          accesskeyid: ${{ secrets.R2_ACCESS_KEY_ID }}
          secretaccesskey: ${{ secrets.R2_SECRET_ACCESS_KEY }}
          bucket: apollo-router
          file: router.tar.gz
          destination: ${{ inputs.version }}/${{ env.RUST_TARGET_OS }}/router.tar.gz

      - name: Upload to R2 (latest)
        if: ${{ inputs.publish && inputs.latest }}
        uses: randomairborne/r2-release@9cbc35a2039ee2ef453a6988cd2a85bb2d7ba8af # v1.0.2
        with:
          endpoint: https://6d5bc18cd8d13babe7ed321adba3d8ae.r2.cloudflarestorage.com
          accesskeyid: ${{ secrets.R2_ACCESS_KEY_ID }}
          secretaccesskey: ${{ secrets.R2_SECRET_ACCESS_KEY }}
          bucket: apollo-router
          file: router.tar.gz
          destination: latest/${{ env.RUST_TARGET_OS }}/router.tar.gz
