name: Publish Docker Images

on:
  release:
    types: [published]
  workflow_dispatch:
    inputs:
      tag:
        description: 'Release tag (e.g., v4.34.0)'
        required: true
        type: string

concurrency:
  group: docker-publish-${{ github.event.release.tag_name || inputs.tag }}
  cancel-in-progress: false

jobs:
  publish:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: read
      packages: write

    steps:
      - name: Extract version from release tag
        id: version
        run: |
          TAG="${{ github.event.release.tag_name || inputs.tag }}"
          VERSION="${TAG#v}"
          
          # Detect if this is a prerelease (RC, alpha, beta)
          IS_PRERELEASE="false"
          if [[ "$VERSION" =~ -rc\.[0-9]+$ ]] || [[ "$VERSION" =~ -alpha\.[0-9]+$ ]] || [[ "$VERSION" =~ -beta\.[0-9]+$ ]]; then
            IS_PRERELEASE="true"
            echo "Detected prerelease version - will NOT update :latest tag"
          fi
          
          echo "tag=${TAG}" >> $GITHUB_OUTPUT
          echo "version=${VERSION}" >> $GITHUB_OUTPUT
          echo "is_prerelease=${IS_PRERELEASE}" >> $GITHUB_OUTPUT
          echo "Publishing Docker images for ${TAG} (prerelease: ${IS_PRERELEASE})"

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Copy staging images to final tags
        run: |
          TAG="${{ steps.version.outputs.tag }}"
          VERSION="${{ steps.version.outputs.version }}"
          STAGING_TAG="staging-${TAG}"

          # Retry function for transient Docker Hub failures
          retry_push() {
            local cmd="$1"
            local max_attempts=3
            local attempt=1
            local delay=10

            while [ $attempt -le $max_attempts ]; do
              echo "Attempt $attempt of $max_attempts..."
              if eval "$cmd"; then
                return 0
              fi
              echo "Attempt $attempt failed"
              if [ $attempt -lt $max_attempts ]; then
                echo "Waiting ${delay}s before retry..."
                sleep $delay
                delay=$((delay * 2))
              fi
              attempt=$((attempt + 1))
            done
            echo "All $max_attempts attempts failed"
            return 1
          }

          IS_PRERELEASE="${{ steps.version.outputs.is_prerelease }}"
          
          echo "Copying pulse staging image to final tags..."
          if [ "$IS_PRERELEASE" = "true" ]; then
            # For prereleases, only tag with version - do NOT update :latest
            retry_push "docker buildx imagetools create \
              --tag rcourtman/pulse:${TAG} \
              --tag rcourtman/pulse:${VERSION} \
              --tag ghcr.io/${{ github.repository_owner }}/pulse:${TAG} \
              --tag ghcr.io/${{ github.repository_owner }}/pulse:${VERSION} \
              ghcr.io/${{ github.repository_owner }}/pulse:${STAGING_TAG}"
          else
            # For stable releases, also update :latest
            retry_push "docker buildx imagetools create \
              --tag rcourtman/pulse:${TAG} \
              --tag rcourtman/pulse:${VERSION} \
              --tag rcourtman/pulse:latest \
              --tag ghcr.io/${{ github.repository_owner }}/pulse:${TAG} \
              --tag ghcr.io/${{ github.repository_owner }}/pulse:${VERSION} \
              --tag ghcr.io/${{ github.repository_owner }}/pulse:latest \
              ghcr.io/${{ github.repository_owner }}/pulse:${STAGING_TAG}"
          fi

          echo "Copying pulse-docker-agent staging image to final tags..."
          if [ "$IS_PRERELEASE" = "true" ]; then
            # For prereleases, only tag with version - do NOT update :latest
            retry_push "docker buildx imagetools create \
              --tag rcourtman/pulse-docker-agent:${TAG} \
              --tag rcourtman/pulse-docker-agent:${VERSION} \
              --tag ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${TAG} \
              --tag ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${VERSION} \
              ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${STAGING_TAG}"
          else
            # For stable releases, also update :latest
            retry_push "docker buildx imagetools create \
              --tag rcourtman/pulse-docker-agent:${TAG} \
              --tag rcourtman/pulse-docker-agent:${VERSION} \
              --tag rcourtman/pulse-docker-agent:latest \
              --tag ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${TAG} \
              --tag ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${VERSION} \
              --tag ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:latest \
              ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${STAGING_TAG}"
          fi

      - name: Output image information
        run: |
          IS_PRERELEASE="${{ steps.version.outputs.is_prerelease }}"
          echo "✅ Docker images published successfully!"
          echo ""
          echo "Server images:"
          echo "  - rcourtman/pulse:${{ steps.version.outputs.tag }}"
          echo "  - rcourtman/pulse:${{ steps.version.outputs.version }}"
          if [ "$IS_PRERELEASE" != "true" ]; then
            echo "  - rcourtman/pulse:latest"
          fi
          echo ""
          echo "Agent images:"
          echo "  - rcourtman/pulse-docker-agent:${{ steps.version.outputs.tag }}"
          echo "  - rcourtman/pulse-docker-agent:${{ steps.version.outputs.version }}"
          if [ "$IS_PRERELEASE" != "true" ]; then
            echo "  - rcourtman/pulse-docker-agent:latest"
          fi
          echo ""
          if [ "$IS_PRERELEASE" = "true" ]; then
            echo "Note: :latest tags were NOT updated (this is a prerelease)"
          fi
