#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
name: PR validation
on:
  pull_request:
    branches: ['master']

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  unit-tests:
    name: Run unit tests
    runs-on: ubuntu-22.04
    timeout-minutes: 120

    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js 18
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Run Test
        run: |
          ./tests/run-unit-tests.sh

  validation-yarn:
    name: Validation use yarn install
    runs-on: ubuntu-22.04
    timeout-minutes: 120

    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js 18
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Use yarn install
        run: |
          yarn install --ignore-scripts

  macos-napi:
    name: Build NAPI macos - Node ${{matrix.nodejs}} - ${{matrix.arch}}
    runs-on: macos-latest
    timeout-minutes: 3000

    strategy:
      fail-fast: false
      matrix:
        arch:
          - x64
          - arm64
        nodejs:
          - 18
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.nodejs }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.nodejs }}
          cache: 'npm'

      - name: Cache Dependencies
        id: cache-dependencies
        uses: actions/cache@v3
        with:
          path: pkg/mac/build
          key: ${{ runner.os }}-${{ matrix.arch }}-mac-${{ hashFiles('pkg/mac/build-cpp-deps-lib.sh') }}

      - name: Add arch env vars
        run: |
          if [ "${{ matrix.arch }}" = "x64" ]; then
            echo "ARCH=x86_64" >> $GITHUB_ENV
          else
            echo "ARCH=${{ matrix.arch }}" >> $GITHUB_ENV
          fi

      - name: Build CPP dependencies lib
        if: steps.cache-dependencies.outputs.cache-hit != 'true'
        run: |
          export ARCH=${{ env.ARCH }}
          pkg/mac/build-cpp-deps-lib.sh

      - name: Build CPP lib
        if: steps.cache-pulsar.outputs.cache-hit != 'true'
        run: |
          export ARCH=${{ env.ARCH }}
          pkg/mac/build-cpp-lib.sh

      - name: Build Node binaries lib
        run: |
          npm install --ignore-scripts
          npx node-pre-gyp configure --target_arch=${{ matrix.arch }}
          npx node-pre-gyp build --target_arch=${{ matrix.arch }}

      - name: Test loading Node binaries lib
        if: matrix.arch == 'x64'
        run: |
          node pkg/load_test.js

      - name: Package Node binaries lib
        run: |
          npx node-pre-gyp package --target_arch=${{ matrix.arch }}

  linux-napi:
    name: Build NAPI ${{matrix.image}} - Node ${{matrix.nodejs}} - ${{matrix.cpu.platform}}
    runs-on: ubuntu-22.04
    timeout-minutes: 3000

    strategy:
      fail-fast: false
      matrix:
        image:
          - 'linux_glibc'
          - 'linux_musl'
        nodejs:
          - 18
        cpu:
          - {arch: 'x86_64', platform: 'x86_64'}
          - {arch: 'aarch64', platform: 'arm64'}

    steps:
      - name: checkout
        uses: actions/checkout@v3

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Build Linux Docker image
        uses: docker/build-push-action@v3
        with:
          file: ./pkg/linux/Dockerfile_${{matrix.image}}
          load: true
          tags: build:latest
          platforms: linux/${{matrix.cpu.arch}}
          build-args: |
            PLATFORM=${{matrix.cpu.platform}}
            ARCH=${{matrix.cpu.arch}}
            NODE_VERSION=${{matrix.nodejs}}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Build and Test NAPI file
        run: |
          docker run -i -v $PWD:/pulsar-client-node build:latest \
              /pulsar-client-node/pkg/linux/build-napi-inside-docker.sh

      - name: Test NAPI file in other containers
        if: matrix.image == 'linux_glibc'
        run: |
          ./tests/load-test.sh node:16-buster ${{matrix.cpu.platform}}
          ./tests/load-test.sh node:16-bullseye ${{matrix.cpu.platform}}
          ./tests/load-test.sh node:19-buster ${{matrix.cpu.platform}}
          ./tests/load-test.sh node:19-bullseye ${{matrix.cpu.platform}}

  windows-napi:
    name: Build NAPI windows - Node ${{matrix.nodejs}} - ${{matrix.arch}}
    runs-on: windows-2022
    timeout-minutes: 3000

    strategy:
      fail-fast: false
      matrix:
        arch:
          - x64
          - x86
        nodejs:
          - 18
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.nodejs }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.nodejs }}
          architecture: ${{ matrix.arch }}
          cache: 'npm'

      - name: Cache CPP Client
        id: cache-dependencies
        uses: actions/cache@v3
        with:
          path: pkg/windows/
          key: ${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('pulsar-client-cpp.txt') }}

      - name: Add env vars
        shell: bash
        run: |
          if [ "${{ matrix.arch }}" = "x86" ]; then
            echo "TARGET=ia32" >> $GITHUB_ENV
          else
            echo "TARGET=${{ matrix.arch }}" >> $GITHUB_ENV
          fi

      - name: Download CPP Client
        if: steps.cache-dependencies.outputs.cache-hit != 'true'
        run: |
          pkg/windows/download-cpp-client.bat ${{ matrix.arch }}

      - name: Build Node binaries lib
        run: |
          npm install --ignore-scripts
          npx node-pre-gyp configure --target_arch=${{ env.TARGET }}
          npx node-pre-gyp build --target_arch=${{ env.TARGET }}

      - name: Test loading Node binaries lib
        run: |
          node pkg/load_test.js

      - name: Package Node binaries lib
        run: |
          npx node-pre-gyp package --target_arch=${{ env.TARGET }}
