# Tekton Task to Detect Changed Services
# This task analyzes git changes to determine which services need to be built

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: detect-changed-services
  namespace: {{ .Release.Namespace }}
  labels:
    app.kubernetes.io/name: {{ .Values.labels.app.name }}
    app.kubernetes.io/component: detection
spec:
  workspaces:
    - name: source
      description: Workspace containing the source code
  results:
    - name: changed-services
      description: Comma-separated list of changed services
  steps:
    - name: detect-changes
      image: alpine/git:2.43.0
      securityContext:
        runAsNonRoot: true
        runAsUser: 65532
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
        seccompProfile:
          type: RuntimeDefault
      env:
        - name: HOME
          value: /tekton/home
      script: |
        #!/bin/sh
        set -e

        # Mark workspace as safe directory to avoid ownership issues
        git config --global --add safe.directory "$(workspaces.source.path)"

        cd $(workspaces.source.path)

        echo "Git log (last 3 commits):"
        git log --oneline -3 || echo "Cannot get git log"

        # Check if we have enough history for comparison
        COMMIT_COUNT=$(git rev-list --count HEAD 2>/dev/null || echo "0")
        echo "Commit count in history: $COMMIT_COUNT"

        if [ "$COMMIT_COUNT" -lt 2 ]; then
          echo "Not enough git history for change detection (need at least 2 commits)"
          echo "Building all services as fallback"
          echo "all" > $(results.changed-services.path)
          exit 0
        fi

        # Get the list of changed files
        CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || echo "")

        if [ -z "$CHANGED_FILES" ]; then
          # Empty commit or something unusual - skip build
          echo "No file changes detected in last commit"
          echo "infrastructure" > $(results.changed-services.path)
          exit 0
        fi

        echo "Changed files:"
        echo "$CHANGED_FILES"

        # Initialize empty string to collect changed services
        CHANGED_SERVICES=""

        # Helper function to add service if not already present
        add_service() {
          svc="$1"
          case ",$CHANGED_SERVICES," in
            *",$svc,"*) ;;  # Already present
            *)
              if [ -z "$CHANGED_SERVICES" ]; then
                CHANGED_SERVICES="$svc"
              else
                CHANGED_SERVICES="$CHANGED_SERVICES,$svc"
              fi
              ;;
          esac
        }

        # Check for changes in services/ directory
        for svc in $(echo "$CHANGED_FILES" | grep '^services/' | cut -d'/' -f2 | sort -u); do
          if [ -n "$svc" ]; then
            add_service "$svc"
          fi
        done

        # Check for changes in gateway/ directory
        if echo "$CHANGED_FILES" | grep -q '^gateway/'; then
          add_service "gateway"
        fi

        # Check for changes in frontend/ directory
        if echo "$CHANGED_FILES" | grep -q '^frontend/'; then
          add_service "frontend"
        fi

        # Check for changes in shared/ directory
        # shared/ contains code used by services and gateway (NOT frontend), so rebuild them
        if echo "$CHANGED_FILES" | grep -q '^shared/'; then
          echo "Detected changes in shared/ - triggering rebuild of all services and gateway"
          echo "services-and-gateway" > $(results.changed-services.path)
          exit 0
        fi

        if [ -z "$CHANGED_SERVICES" ]; then
          # Changes are in infrastructure or other non-service files
          echo "Detected: infrastructure changes only"
          echo "infrastructure" > $(results.changed-services.path)
        else
          echo "Detected changed services: $CHANGED_SERVICES"
          echo "$CHANGED_SERVICES" > $(results.changed-services.path)
        fi