name: cli-deno-tests

on:
  push:
    branches:
      - main
      - beta
    paths:
      - '.github/workflows/cli-deno-tests.yml'
      - 'src/apps/cli/**'
      - 'test/bench-network/**'
      - 'package.json'
      - 'package-lock.json'
  pull_request:
    paths:
      - '.github/workflows/cli-deno-tests.yml'
      - 'src/apps/cli/**'
      - 'test/bench-network/**'
      - 'package.json'
      - 'package-lock.json'
  workflow_dispatch:
    inputs:
      test_task:
        description: 'Deno test task to run'
        type: choice
        options:
          - test:ci
          - test:local
          - test:e2e-matrix
        default: test:ci
      enable_debug:
        description: 'Enable verbose and debug logging'
        type: boolean
        default: false
      use_coturn:
        description: 'Enable local coturn container for P2P tests'
        type: boolean
        default: false

permissions:
  contents: read

jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      task_matrix: ${{ steps.select.outputs.task_matrix }}
    steps:
      - name: Select task matrix
        id: select
        shell: bash
        run: |
          set -euo pipefail
          SELECTED_TASK="${{ github.event_name == 'workflow_dispatch' && inputs.test_task || 'test:ci' }}"
          echo "[INFO] Selected task set: $SELECTED_TASK"

          case "$SELECTED_TASK" in
            test:ci)
              TASK_MATRIX='["test:setup-put-cat","test:mirror","test:daemon","test:push-pull","test:decoupled-vault","test:sync-two-local","test:sync-locked-remote","test:remote-commands","test:e2e-matrix:couchdb-enc0","test:e2e-matrix:couchdb-enc1","test:e2e-matrix:minio-enc0","test:e2e-matrix:minio-enc1"]'
              ;;
            test:local)
              TASK_MATRIX='["test:setup-put-cat","test:mirror","test:daemon"]'
              ;;
            test:e2e-matrix)
              TASK_MATRIX='["test:e2e-matrix:couchdb-enc0","test:e2e-matrix:couchdb-enc1","test:e2e-matrix:minio-enc0","test:e2e-matrix:minio-enc1"]'
              ;;
            *)
              echo "[ERROR] Unknown task set: $SELECTED_TASK" >&2
              exit 1
              ;;
          esac

          echo "task_matrix=$TASK_MATRIX" >> "$GITHUB_OUTPUT"

  test:
    needs: prepare
    runs-on: ubuntu-latest
    timeout-minutes: 60
    env:
      DENO_DIR: ~/.cache/deno
    strategy:
      fail-fast: false
      matrix:
        task: ${{ fromJson(needs.prepare.outputs.task_matrix) }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '24.x'
          cache: 'npm'
          cache-dependency-path: package-lock.json

      - name: Setup Deno
        uses: denoland/setup-deno@v2
        with:
          deno-version: v2.x

      - name: Cache Deno dependencies
        uses: actions/cache@v4
        with:
          path: ~/.cache/deno
          key: ${{ runner.os }}-deno-${{ hashFiles('src/apps/cli/testdeno/deno.lock', 'src/apps/cli/testdeno/deno.json') }}
          restore-keys: |
            ${{ runner.os }}-deno-

      - name: Install dependencies
        run: npm ci

      - name: Build CLI
        working-directory: src/apps/cli
        run: npm run build

      - name: Create .test.env
        working-directory: src/apps/cli
        run: |
          cat <<EOF > .test.env
          hostname=http://127.0.0.1:5989/
          dbname=livesync-test-db-ci
          username=admin
          password=testpassword
          minioEndpoint=http://127.0.0.1:9000
          accessKey=minioadmin
          secretKey=minioadmin
          bucketName=livesync-test-bucket-ci
          EOF

      - name: Run Deno tests
        working-directory: src/apps/cli/testdeno
        env:
          LIVESYNC_DOCKER_MODE: native
          LIVESYNC_CLI_RETRY: 3
          LIVESYNC_CLI_DEBUG: ${{ inputs.enable_debug == true && '1' || '0' }}
          LIVESYNC_CLI_VERBOSE: ${{ inputs.enable_debug == true && '1' || '0' }}
          LIVESYNC_USE_COTURN: ${{ inputs.use_coturn == true && '1' || '0' }}
        run: |
          TASK="${{ matrix.task }}"
          echo "[INFO] Running Deno task: $TASK"
          deno task "$TASK"

      - name: Stop leftover containers
        if: always()
        run: |
          docker stop couchdb-test minio-test relay-test coturn-test >/dev/null 2>&1 || true
          docker rm couchdb-test minio-test relay-test coturn-test >/dev/null 2>&1 || true

  compose-p2p-e2e:
    runs-on: ubuntu-latest
    timeout-minutes: 45
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Show Docker versions
        run: |
          docker --version
          docker compose version

      - name: Run Compose CLI P2P E2E
        env:
          CLI_E2E_TASK: test:p2p:ci
          RELAY: ws://nostr-relay:7777/
          PEERS_TIMEOUT: '20'
          SYNC_TIMEOUT: '60'
          LIVESYNC_USE_COTURN: '0'
          TURN_SERVERS: none
          LIVESYNC_P2P_PEERS_RETRY: '1'
          LIVESYNC_P2P_RELAY_READY_TIMEOUT_MS: '60000'
          BENCH_LIVESYNC_TEST_TEE: '0'
        run: docker compose -f test/bench-network/compose.yml run --build --rm bench-runner run-livesync-cli-e2e

      - name: Show Compose diagnostics
        if: failure()
        run: |
          docker compose -f test/bench-network/compose.yml ps
          docker compose -f test/bench-network/compose.yml logs --no-color couchdb nostr-relay || true

      - name: Stop Compose services
        if: always()
        run: docker compose -f test/bench-network/compose.yml down -v --remove-orphans
