#!/bin/bash
# Generate dynamic test matrix based on detected changes
# Reads changes.json, outputs test-matrix.yml as a child pipeline config

set -e

# CRITICAL: Tags ALWAYS run full test matrix, no matter what
if [ -n "$CI_COMMIT_TAG" ]; then
    echo "Tag detected ($CI_COMMIT_TAG) - forcing full test matrix"
    TEST_ALL="true"
    CHANGED_LANGS=""
else
    # Read changes from detect-changes output
    CHANGES=$(cat changes.json)
    CHANGED_LANGS=$(echo "$CHANGES" | jq -r '.changed_langs[]' 2>/dev/null || echo "")
    TEST_ALL=$(echo "$CHANGES" | jq -r '.test_all' 2>/dev/null || echo "false")
fi

# Fetch ALL supported languages from the unsandbox API (the source of truth)
ALL_SDKS=$(curl -s "https://api.unsandbox.com/languages" | jq -r '.languages[]' | tr '\n' ' ')
if [ -z "$ALL_SDKS" ]; then
    # Fallback if API is unavailable
    ALL_SDKS="python javascript typescript ruby perl php lua bash go rust java kotlin c cpp"
    echo "Warning: Could not fetch languages from API, using fallback list"
fi
echo "Available SDKs from API: $ALL_SDKS"

# Test ALL languages - the sandbox has compilers for compiled languages too!

if [ "$TEST_ALL" = "true" ]; then
    LANGS="$ALL_SDKS"
elif [ -z "$CHANGED_LANGS" ]; then
    # No changes - create minimal valid child pipeline that does nothing
    cat > test-matrix.yml << 'EOF'
# No SDK changes detected - skip tests
stages:
  - skip

skip-tests:
  stage: skip
  tags:
    - build
  script:
    - echo "No SDK changes detected - skipping inception tests"
EOF
    echo "No SDK changes - created skip pipeline"
    cat test-matrix.yml
    exit 0
else
    LANGS="$CHANGED_LANGS"
fi

# Count languages
LANG_COUNT=$(echo $LANGS | wc -w)
echo "Testing $LANG_COUNT languages: $LANGS"

# Generate child pipeline config
cat > test-matrix.yml << 'EOF'
# Dynamically generated child pipeline - inception tests
# Each test runs: build/un → unsandbox → SDK → unsandbox → test code

stages:
  - build
  - cleanup
  - test

default:
  tags:
    - build

# CI variables inherited from parent pipeline

build-cli:
  stage: build
  script:
    - bash scripts/build-clients.sh
  artifacts:
    paths:
      - build/
    expire_in: 1 hour

# Cleanup orphaned test resources before fan-out to avoid concurrency limits
# ONLY targets resources with "test-" in the name to avoid destroying real services
cleanup-services:
  stage: cleanup
  needs:
    - build-cli
  script:
    - echo "=== Cleaning up orphaned test resources ==="
    - |
      # Cleanup test services (test-python-*, test-javascript-*, etc.)
      echo "Checking for orphaned test services..."
      SERVICES=$(build/un service --list 2>/dev/null | grep -E "test-[a-z]+-[0-9]+" || true)
      if [ -n "$SERVICES" ]; then
        echo "$SERVICES" | while read -r line; do
          SVC=$(echo "$line" | grep -oE 'unsb-service-[a-f0-9]+' || true)
          if [ -n "$SVC" ]; then
            echo "Destroying test service: $SVC"
            build/un service --destroy "$SVC" || true
          fi
        done
      fi
      echo "Service cleanup complete"
    - |
      # Cleanup test sessions
      echo "Checking for orphaned test sessions..."
      SESSIONS=$(build/un session --list 2>/dev/null | grep -E "test-[a-z]+-[0-9]+" || true)
      if [ -n "$SESSIONS" ]; then
        echo "$SESSIONS" | while read -r line; do
          SESS=$(echo "$line" | grep -oE 'unsb-session-[a-f0-9-]+' || true)
          if [ -n "$SESS" ]; then
            echo "Killing test session: $SESS"
            build/un session --kill "$SESS" || true
          fi
        done
      fi
      echo "Session cleanup complete"
    - |
      # Cleanup test snapshots
      echo "Checking for orphaned test snapshots..."
      SNAPSHOTS=$(build/un snapshot --list 2>/dev/null | grep -E "test-[a-z]+-[0-9]+" || true)
      if [ -n "$SNAPSHOTS" ]; then
        echo "$SNAPSHOTS" | while read -r line; do
          SNAP=$(echo "$line" | grep -oE 'unsb-snapshot-[a-f0-9-]+' || true)
          if [ -n "$SNAP" ]; then
            echo "Deleting test snapshot: $SNAP"
            build/un snapshot --delete "$SNAP" || true
          fi
        done
      fi
      echo "Snapshot cleanup complete"
    - |
      # Cleanup test images
      echo "Checking for orphaned test images..."
      IMAGES=$(build/un image --list 2>/dev/null | grep -E "test-[a-z]+-[0-9]+" || true)
      if [ -n "$IMAGES" ]; then
        echo "$IMAGES" | while read -r line; do
          IMG=$(echo "$line" | grep -oE 'unsb-image-[a-f0-9-]+' || true)
          if [ -n "$IMG" ]; then
            echo "Deleting test image: $IMG"
            build/un image --delete "$IMG" || true
          fi
        done
      fi
      echo "Image cleanup complete"
    - echo "=== Cleanup complete ==="
  allow_failure: true

test:
  stage: test
  needs:
    - build-cli
    - cleanup-services
  parallel:
    matrix:
EOF

# Add each language as a parallel job
for LANG in $LANGS; do
    echo "      - SDK_LANG: $LANG" >> test-matrix.yml
done

# Complete the test job template
cat >> test-matrix.yml << 'EOF'
  script:
    - bash scripts/test-sdk.sh "$SDK_LANG"
  artifacts:
    reports:
      junit: "test-results-$SDK_LANG/test-results.xml"
    paths:
      - "test-results-$SDK_LANG/"
    expire_in: 30 days
    when: always
  allow_failure: true
  retry: 1
EOF

echo ""
echo "Generated test-matrix.yml with $LANG_COUNT parallel jobs:"
cat test-matrix.yml
