# Tekton Update GitOps Task for Bakery-IA CI/CD
# This task updates GitOps manifests with new image tags

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: update-gitops
  namespace: {{ .Release.Namespace }}
  labels:
    app.kubernetes.io/name: {{ .Values.labels.app.name }}
    app.kubernetes.io/component: gitops
spec:
  workspaces:
    - name: source
      description: Workspace containing the source code
    - name: git-credentials
      description: Git credentials for pushing changes
  params:
    - name: services
      type: string
      description: Comma-separated list of services to update
    - name: registry
      type: string
      description: Container registry URL
    - name: git-revision
      type: string
      description: Git revision to tag images with
    - name: git-branch
      type: string
      description: Git branch to push changes to
    - name: dry-run
      type: string
      description: Dry run mode - don't push changes
      default: "false"
  steps:
    - name: update-manifests
      image: alpine/git:2.43.0
      securityContext:
        runAsNonRoot: true
        runAsUser: 65532
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
        seccompProfile:
          type: RuntimeDefault
      workingDir: $(workspaces.source.path)
      env:
        - name: HOME
          value: /tekton/home
        - name: GIT_USERNAME
          valueFrom:
            secretKeyRef:
              name: gitea-git-credentials
              key: username
        - name: GIT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: gitea-git-credentials
              key: password
      script: |
        #!/bin/sh
        set -e

        echo "============================================"
        echo "Updating GitOps Manifests"
        echo "Services: $(params.services)"
        echo "Registry: $(params.registry)"
        echo "Revision: $(params.git-revision)"
        echo "Branch: $(params.git-branch)"
        echo "Dry run: $(params.dry-run)"
        echo "============================================"

        # Configure git
        git config --global user.email "ci@bakery-ia.local"
        git config --global user.name "bakery-ia-ci"
        # Mark directories as safe to avoid ownership issues
        git config --global --add safe.directory /tmp/gitops
        git config --global --add safe.directory "$(workspaces.source.path)"

        # Clone the main repository (not a separate gitops repo)
        # Use internal cluster DNS which works in all environments
        REPO_URL="https://${GIT_USERNAME}:${GIT_PASSWORD}@gitea-http.gitea.svc.cluster.local:3000/bakery-admin/bakery-ia.git"
        git clone "$REPO_URL" /tmp/gitops

        cd /tmp/gitops

        # Switch to target branch
        git checkout "$(params.git-branch)" || git checkout -b "$(params.git-branch)"

        # Update image tags in Kubernetes manifests
        for service in $(echo "$(params.services)" | tr ',' '\n'); do
          service=$(echo "$service" | xargs)  # Trim whitespace
          if [ -n "$service" ] && [ "$service" != "none" ] && [ "$service" != "infrastructure" ] && [ "$service" != "shared" ]; then
            echo "Updating manifest for service: $service"

            # Format service name for directory (convert from kebab-case to snake_case if needed)
            # Handle special cases like demo-session -> demo_session, alert-processor -> alert_processor, etc.
            formatted_service=$(echo "$service" | sed 's/-/_/g')

            # For gateway and frontend, they have different directory structures
            if [ "$service" = "gateway" ]; then
              MANIFEST_PATH="infrastructure/platform/gateway/gateway-service.yaml"
              IMAGE_NAME="gateway"  # gateway image name is just "gateway"
            elif [ "$service" = "frontend" ]; then
              MANIFEST_PATH="infrastructure/services/microservices/frontend/frontend-service.yaml"
              IMAGE_NAME="dashboard"  # frontend service uses "dashboard" as image name
            else
              # For microservices, look in the microservices directory
              # Convert service name to directory format (kebab-case)
              service_dir=$(echo "$service" | sed 's/_/-/g')

              # Check for different possible manifest file names
              if [ -f "infrastructure/services/microservices/$service_dir/deployment.yaml" ]; then
                MANIFEST_PATH="infrastructure/services/microservices/$service_dir/deployment.yaml"
              elif [ -f "infrastructure/services/microservices/$service_dir/${formatted_service}-service.yaml" ]; then
                MANIFEST_PATH="infrastructure/services/microservices/$service_dir/${formatted_service}-service.yaml"
              elif [ -f "infrastructure/services/microservices/$service_dir/${service_dir}-service.yaml" ]; then
                MANIFEST_PATH="infrastructure/services/microservices/$service_dir/${service_dir}-service.yaml"
              else
                # Default to the standard naming pattern
                MANIFEST_PATH="infrastructure/services/microservices/$service_dir/${formatted_service}-service.yaml"
              fi

              # For most services, the image name follows the pattern service-name-service
              IMAGE_NAME="${service_dir}-service"
            fi

            # Update the image tag in the deployment YAML
            if [ -f "$MANIFEST_PATH" ]; then
              # Update image reference from bakery/image_name:tag to registry/image_name:git_revision
              # Handle various image name formats that might exist in the manifests
              sed -i "s|image: bakery/${IMAGE_NAME}:.*|image: $(params.registry)/${IMAGE_NAME}:$(params.git-revision)|g" "$MANIFEST_PATH"
              # Also handle the case where the image name might be formatted differently
              sed -i "s|image: bakery/${service}:.*|image: $(params.registry)/${service}:$(params.git-revision)|g" "$MANIFEST_PATH"
              sed -i "s|image: bakery/${formatted_service}:.*|image: $(params.registry)/${formatted_service}:$(params.git-revision)|g" "$MANIFEST_PATH"

              echo "Updated image in: $MANIFEST_PATH for image: bakery/${IMAGE_NAME}:* -> $(params.registry)/${IMAGE_NAME}:$(params.git-revision)"
            else
              echo "Warning: Manifest file not found: $MANIFEST_PATH"
            fi
          fi
        done

        # Commit and push changes (unless dry-run)
        if [ "$(params.dry-run)" != "true" ]; then
          git add .
          git status
          if ! git diff --cached --quiet; then
            git commit -m "Update images for services: $(params.services) [skip ci]"
            git push origin "$(params.git-branch)"
            echo "GitOps manifests updated successfully"
          else
            echo "No changes to commit"
          fi
        else
          echo "Dry run mode - changes not pushed"
          git status
          git diff
        fi
      resources:
        limits:
          cpu: 500m
          memory: 512Mi
        requests:
          cpu: 100m
          memory: 128Mi