name: Test

on:
  push:
    branches: [develop]
  pull_request:
    branches: [develop]

concurrency:
  group: test-${{ gitea.ref }}
  cancel-in-progress: true

env:
  NODE_VERSION: "20"
  # TODO: Remove after installing internal CA certificate on the runner
  GIT_SSL_NO_VERIFY: "true"
  NPM_CONFIG_FETCH_RETRIES: "5"
  NPM_CONFIG_FETCH_RETRY_MINTIMEOUT: "20000"
  NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT: "120000"
  NPM_CONFIG_INCLUDE: "optional"

jobs:
  type-check:
    name: Type Check (all packages)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: corepack enable && corepack prepare npm@10.5.0 --activate
      - name: Install dependencies
        run: |
          for attempt in 1 2 3; do
            npm ci --include=optional && break
            if [ "$attempt" = "3" ]; then
              exit 1
            fi
            npm cache verify || true
            sleep "$((attempt * 10))"
          done
      - name: Repair Rollup optional dependency on Linux ARM64
        run: |
          ARCH="$(uname -m)"
          if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
            ROLLUP_VERSION="$(node -p "require('./node_modules/rollup/package.json').version")"
            for attempt in 1 2 3; do
              npm install --no-save --include=optional "@rollup/rollup-linux-arm64-gnu@$ROLLUP_VERSION" && break
              if [ "$attempt" = "3" ]; then
                exit 1
              fi
              npm cache verify || true
              sleep "$((attempt * 10))"
            done
            node -e "require('@rollup/rollup-linux-arm64-gnu')"
          fi
      - run: npm run db:generate
      - run: npm run type-check

  api-tests:
    name: API Unit Tests
    runs-on: ubuntu-latest
    needs: type-check
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: corepack enable && corepack prepare npm@10.5.0 --activate
      - name: Install dependencies
        run: |
          for attempt in 1 2 3; do
            npm ci --include=optional && break
            if [ "$attempt" = "3" ]; then
              exit 1
            fi
            npm cache verify || true
            sleep "$((attempt * 10))"
          done
      - name: Repair Rollup optional dependency on Linux ARM64
        run: |
          ARCH="$(uname -m)"
          if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
            ROLLUP_VERSION="$(node -p "require('./node_modules/rollup/package.json').version")"
            for attempt in 1 2 3; do
              npm install --no-save --include=optional "@rollup/rollup-linux-arm64-gnu@$ROLLUP_VERSION" && break
              if [ "$attempt" = "3" ]; then
                exit 1
              fi
              npm cache verify || true
              sleep "$((attempt * 10))"
            done
            node -e "require('@rollup/rollup-linux-arm64-gnu')"
          fi
      - run: npm run db:generate
      - run: npm run test:api

  homepage-tests:
    name: Homepage Unit Tests
    runs-on: ubuntu-latest
    needs: type-check
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: corepack enable && corepack prepare npm@10.5.0 --activate
      - name: Install dependencies
        run: |
          for attempt in 1 2 3; do
            npm ci --include=optional && break
            if [ "$attempt" = "3" ]; then
              exit 1
            fi
            npm cache verify || true
            sleep "$((attempt * 10))"
          done
      - name: Repair Rollup optional dependency on Linux ARM64
        run: |
          ARCH="$(uname -m)"
          if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
            ROLLUP_VERSION="$(node -p "require('./node_modules/rollup/package.json').version")"
            for attempt in 1 2 3; do
              npm install --no-save --include=optional "@rollup/rollup-linux-arm64-gnu@$ROLLUP_VERSION" && break
              if [ "$attempt" = "3" ]; then
                exit 1
              fi
              npm cache verify || true
              sleep "$((attempt * 10))"
            done
            node -e "require('@rollup/rollup-linux-arm64-gnu')"
          fi
      - run: npm run build --workspace @rentaldrivego/types
      - run: npm run test:homepage

  storefront-tests:
    name: Storefront Unit Tests
    runs-on: ubuntu-latest
    needs: type-check
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: corepack enable && corepack prepare npm@10.5.0 --activate
      - name: Install dependencies
        run: |
          for attempt in 1 2 3; do
            npm ci --include=optional && break
            if [ "$attempt" = "3" ]; then
              exit 1
            fi
            npm cache verify || true
            sleep "$((attempt * 10))"
          done
      - name: Repair Rollup optional dependency on Linux ARM64
        run: |
          ARCH="$(uname -m)"
          if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
            ROLLUP_VERSION="$(node -p "require('./node_modules/rollup/package.json').version")"
            for attempt in 1 2 3; do
              npm install --no-save --include=optional "@rollup/rollup-linux-arm64-gnu@$ROLLUP_VERSION" && break
              if [ "$attempt" = "3" ]; then
                exit 1
              fi
              npm cache verify || true
              sleep "$((attempt * 10))"
            done
            node -e "require('@rollup/rollup-linux-arm64-gnu')"
          fi
      - run: npm run build --workspace @rentaldrivego/types
      - run: npm run test:storefront

  admin-tests:
    name: Admin Unit Tests
    runs-on: ubuntu-latest
    needs: type-check
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: corepack enable && corepack prepare npm@10.5.0 --activate
      - name: Install dependencies
        run: |
          for attempt in 1 2 3; do
            npm ci --include=optional && break
            if [ "$attempt" = "3" ]; then
              exit 1
            fi
            npm cache verify || true
            sleep "$((attempt * 10))"
          done
      - name: Repair Rollup optional dependency on Linux ARM64
        run: |
          ARCH="$(uname -m)"
          if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
            ROLLUP_VERSION="$(node -p "require('./node_modules/rollup/package.json').version")"
            for attempt in 1 2 3; do
              npm install --no-save --include=optional "@rollup/rollup-linux-arm64-gnu@$ROLLUP_VERSION" && break
              if [ "$attempt" = "3" ]; then
                exit 1
              fi
              npm cache verify || true
              sleep "$((attempt * 10))"
            done
            node -e "require('@rollup/rollup-linux-arm64-gnu')"
          fi
      - run: npm run test:admin

  dashboard-tests:
    name: Dashboard Unit Tests
    runs-on: ubuntu-latest
    needs: type-check
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: corepack enable && corepack prepare npm@10.5.0 --activate
      - name: Install dependencies
        run: |
          for attempt in 1 2 3; do
            npm ci --include=optional && break
            if [ "$attempt" = "3" ]; then
              exit 1
            fi
            npm cache verify || true
            sleep "$((attempt * 10))"
          done
      - name: Repair Rollup optional dependency on Linux ARM64
        run: |
          ARCH="$(uname -m)"
          if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
            ROLLUP_VERSION="$(node -p "require('./node_modules/rollup/package.json').version")"
            for attempt in 1 2 3; do
              npm install --no-save --include=optional "@rollup/rollup-linux-arm64-gnu@$ROLLUP_VERSION" && break
              if [ "$attempt" = "3" ]; then
                exit 1
              fi
              npm cache verify || true
              sleep "$((attempt * 10))"
            done
            node -e "require('@rollup/rollup-linux-arm64-gnu')"
          fi
      - run: npm run build --workspace @rentaldrivego/types
      - run: npm run test:dashboard

  integration-tests:
    name: API Integration Tests
    runs-on: ubuntu-latest
    needs: type-check
    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_DB: rentaldrivego_test
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: password
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      redis:
        image: redis:7-alpine
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    env:
      DATABASE_URL: postgresql://postgres:password@postgres:5432/rentaldrivego_test
      REDIS_URL: redis://redis:6379
      NODE_ENV: test
      JWT_SECRET: test-secret
      JWT_EXPIRY: 8h
      FILE_STORAGE_ROOT: /tmp/rentaldrivego-test-storage
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: corepack enable && corepack prepare npm@10.5.0 --activate
      - name: Install dependencies
        run: |
          for attempt in 1 2 3; do
            npm ci --include=optional && break
            if [ "$attempt" = "3" ]; then
              exit 1
            fi
            npm cache verify || true
            sleep "$((attempt * 10))"
          done
      - name: Repair Rollup optional dependency on Linux ARM64
        run: |
          ARCH="$(uname -m)"
          if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
            ROLLUP_VERSION="$(node -p "require('./node_modules/rollup/package.json').version")"
            for attempt in 1 2 3; do
              npm install --no-save --include=optional "@rollup/rollup-linux-arm64-gnu@$ROLLUP_VERSION" && break
              if [ "$attempt" = "3" ]; then
                exit 1
              fi
              npm cache verify || true
              sleep "$((attempt * 10))"
            done
            node -e "require('@rollup/rollup-linux-arm64-gnu')"
          fi
      - run: npm run db:generate
      - run: npm run db:deploy
      - run: npx prisma db push --schema packages/database/prisma/schema.prisma
      - run: npm run test:api:integration
