# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

name: Property Based Tests

on:
  push:
    branches:
      - main
    paths:
      - ".github/workflows/api-tests.yaml"
      - "api/**"
      - "auth/api/http/**"
      - "channels/api/http/**"
      - "clients/api/http/**"
      - "domains/api/http/**"
      - "groups/api/http/**"
      - "journal/api/**"
      - "users/api/**"
      - "bootstrap/api/**"
      - "certs/api/http/**"
      - "readers/api/http/**"
      - "re/api/**"
      - "alarms/api/**"
      - "reports/api/**"
      - "apidocs/openapi/**"
  pull_request:
    branches:
      - main
    paths:
      - ".github/workflows/api-tests.yaml"
      - "api/**"
      - "auth/api/http/**"
      - "channels/api/http/**"
      - "clients/api/http/**"
      - "domains/api/http/**"
      - "groups/api/http/**"
      - "journal/api/**"
      - "users/api/**"
      - "bootstrap/api/**"
      - "certs/api/http/**"
      - "readers/api/http/**"
      - "re/api/**"
      - "alarms/api/**"
      - "reports/api/**"
      - "apidocs/openapi/**"

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

env:
  TOKENS_URL: http://localhost:9002/users/tokens/issue
  CREATE_DOMAINS_URL: http://localhost:9003/domains
  USER_IDENTITY: admin@example.com
  USER_SECRET: 12345678
  DOMAIN_NAME: demo-test
  USERS_URL: http://localhost:9002
  DOMAIN_URL: http://localhost:9003
  CLIENTS_URL: http://localhost:9006
  CHANNELS_URL: http://localhost:9005
  GROUPS_URL: http://localhost:9004
  AUTH_URL: http://localhost:9001
  JOURNAL_URL: http://localhost:9021
  BOOTSTRAP_URL: http://localhost:9013
  CERTS_URL: http://localhost:9019
  READERS_URL: http://localhost:9011
  RE_URL: http://localhost:9008
  ALARMS_URL: http://localhost:8050
  REPORTS_URL: http://localhost:9017

jobs:
  api-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v7
        with:
          fetch-depth: 0

      - name: Install Go
        uses: actions/setup-go@v6
        with:
          go-version-file: go.mod
          cache-dependency-path: "go.sum"

      - name: Check for changes in specific paths
        uses: dorny/paths-filter@v4
        id: changes
        with:
          filters: |
            workflow:
              - ".github/workflows/api-tests.yaml"

            journal:
              - "apidocs/openapi/journal.yaml"
              - "journal/api/**"

            auth:
              - "apidocs/openapi/auth.yaml"
              - "auth/api/http/**"

            domains:
              - "apidocs/openapi/domains.yaml"
              - "domains/api/http/**"

            clients:
              - "apidocs/openapi/clients.yaml"
              - "clients/api/http/**"

            channels:
              - "apidocs/openapi/channels.yaml"
              - "channels/api/http/**"

            groups:
              - "apidocs/openapi/groups.yaml"
              - "groups/api/http/**"

            users:
              - "apidocs/openapi/users.yaml"
              - "users/api/**"

            bootstrap:
              - "apidocs/openapi/bootstrap.yaml"
              - "bootstrap/api/**"

            certs:
              - "apidocs/openapi/certs.yaml"
              - "certs/api/http/**"

            readers:
              - "apidocs/openapi/readers.yaml"
              - "readers/api/http/**"

            re:
              - "apidocs/openapi/rules.yaml"
              - "re/api/**"

            alarms:
              - "apidocs/openapi/alarms.yaml"
              - "alarms/api/**"

            reports:
              - "apidocs/openapi/reports.yaml"
              - "reports/api/**"

      - name: Build images
        run: make all -j $(nproc) && make dockers_dev -j $(nproc)

      - name: Start containers
        run: make run_latest up args="-d" && make run_addons up args="-d"

      - name: Wait for services to be ready
        run: |
          echo "Waiting for services to start..."
          sleep 15

          # Check if services are responding
          for i in {1..30}; do
            if curl -f -s http://localhost:9002/health > /dev/null 2>&1; then
              echo "Services are ready!"
              break
            fi
            echo "Waiting for services... ($i/30)"
            sleep 2
          done

      - name: Set access token
        run: |
          export USER_TOKEN=$(curl -sSX POST $TOKENS_URL -H "Content-Type: application/json" -d "{\"identity\": \"$USER_IDENTITY\",\"secret\": \"$USER_SECRET\"}" | jq -r .access_token)
          export DOMAIN_ID=$(curl -sSX POST $CREATE_DOMAINS_URL -H "Content-Type: application/json" -H "Authorization: Bearer $USER_TOKEN" -d "{\"name\":\"$DOMAIN_NAME\",\"route\":\"$DOMAIN_NAME\"}" | jq -r .id)
          echo "USER_TOKEN=$USER_TOKEN" >> $GITHUB_ENV
          export CLIENT_SECRET=$(magistrala-cli provision test | /usr/bin/grep -Eo '"secret": "[^"]+"' | awk 'NR % 2 == 0' | sed 's/"secret": "\(.*\)"/\1/')
          echo "CLIENT_SECRET=$CLIENT_SECRET" >> $GITHUB_ENV

      - name: Run Users API tests
        if: steps.changes.outputs.users == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/users.yaml
          base-url: ${{ env.USERS_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --exclude-operation-id=requestPasswordReset --phases=examples'

      - name: Run Groups API tests
        if: steps.changes.outputs.groups == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/groups.yaml
          base-url: ${{ env.GROUPS_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Clients API tests
        if: steps.changes.outputs.clients == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/clients.yaml
          base-url: ${{ env.CLIENTS_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Channels API tests
        if: steps.changes.outputs.channels == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/channels.yaml
          base-url: ${{ env.CHANNELS_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Auth API tests
        if: steps.changes.outputs.auth == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/auth.yaml
          base-url: ${{ env.AUTH_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Domains API tests
        if: steps.changes.outputs.domains == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/domains.yaml
          base-url: ${{ env.DOMAIN_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Journal API tests
        if: steps.changes.outputs.journal == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/journal.yaml
          base-url: ${{ env.JOURNAL_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Bootstrap API tests
        if: steps.changes.outputs.bootstrap == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/bootstrap.yaml
          base-url: ${{ env.BOOTSTRAP_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Certs API tests
        if: steps.changes.outputs.certs == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/certs.yaml
          base-url: ${{ env.CERTS_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Readers API tests
        if: steps.changes.outputs.readers == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/readers.yaml
          base-url: ${{ env.READERS_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Rules Engine API tests
        if: steps.changes.outputs.re == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/rules.yaml
          base-url: ${{ env.RE_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Alarms API tests
        if: steps.changes.outputs.alarms == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/alarms.yaml
          base-url: ${{ env.ALARMS_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Run Reports API tests
        if: steps.changes.outputs.reports == 'true' || steps.changes.outputs.workflow == 'true'
        uses: schemathesis/action@v3.0.0
        with:
          schema: apidocs/openapi/reports.yaml
          base-url: ${{ env.REPORTS_URL }}
          checks: all
          args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'

      - name: Stop containers
        if: always()
        run: make run_latest down args="-v" && make run_addons down args="-v"
