name: Build and Publish TimeTracker Docker Image

on:
  push:
    branches: [ main ]
    tags: [ 'v*' ]
  pull_request:
    branches: [ main ]
  release:
    types: [ published ]
  workflow_dispatch:
    inputs:
      version:
        description: 'Custom version tag (e.g., v1.2.3, build-123)'
        required: false
        default: ''

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: drytrix/timetracker

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    strategy:
      matrix:
        include:
          - name: amd64
            platform: linux/amd64
          - name: arm64
            platform: linux/arm64

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Fetch full history for better versioning

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Determine version
        id: version
        run: |
          # Version determination per requirement:
          # - If a version tag is available, use that (release tag or git tag)
          # - Otherwise use dev-{buildnumber}

          if [[ "${{ github.event.inputs.version }}" != "" ]]; then
            VERSION="${{ github.event.inputs.version }}"
            VERSION_SOURCE="manual"
          elif [[ "${{ github.event_name }}" == "release" && "${{ github.event.release.tag_name }}" != "" ]]; then
            VERSION="${{ github.event.release.tag_name }}"
            VERSION_SOURCE="release"
          elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/}
            VERSION_SOURCE="git_tag"
          else
            BUILD_NUMBER=${{ github.run_number }}
            VERSION="dev-${BUILD_NUMBER}"
            VERSION_SOURCE="dev_build"
          fi
          
          # Clean version string (replace invalid characters)
          VERSION=$(echo "$VERSION" | sed 's/[^a-zA-Z0-9._-]/-/g')
          
          # Set outputs
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "version_source=$VERSION_SOURCE" >> $GITHUB_OUTPUT
          echo "branch_name=${BRANCH_NAME:-}" >> $GITHUB_OUTPUT
          echo "build_number=${BUILD_NUMBER:-}" >> $GITHUB_OUTPUT
          
          echo "=== Version Information ==="
          echo "Version: $VERSION"
          echo "Source: $VERSION_SOURCE"
          echo "Branch: ${BRANCH_NAME:-N/A}"
          echo "Build Number: ${BUILD_NUMBER:-N/A}"
          echo "Commit SHA: ${GITHUB_SHA::8}"
          echo "=========================="

      - name: Check files and create combined Dockerfile
        run: |
          echo "--- Checking available files ---"
          pwd
          ls -la
          echo "--- Checking if requirements.txt exists ---"
          if [ -f requirements.txt ]; then
            echo "requirements.txt found:"
            cat requirements.txt
          else
            echo "requirements.txt NOT found!"
            echo "Available .txt files:"
            find . -name "*.txt" -type f
          fi
          
          echo "--- Creating combined Dockerfile ---"
          cp Dockerfile Dockerfile.final
          # Ensure port 8080 is exposed in the final Dockerfile
          if ! grep -q "^EXPOSE 8080" Dockerfile.final; then
            echo "\n# Ensure required port is exposed" >> Dockerfile.final
            echo "EXPOSE 8080" >> Dockerfile.final
          fi
          echo "Combined Dockerfile created successfully"

      - name: Build Docker image
        run: |
          IMAGE_ID=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          VERSION="${{ steps.version.outputs.version }}"
          
          echo "Building Docker image..."
          echo "Image ID: $IMAGE_ID"
          echo "Version: $VERSION"
          
          # Build the Docker image with version label
          docker build \
            -f Dockerfile.final \
            --label "org.opencontainers.image.version=$VERSION" \
            --label "org.opencontainers.image.revision=${{ github.sha }}" \
            --label "org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
            --label "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}" \
            --label "org.opencontainers.image.exposedPorts=8080" \
            --build-arg APP_VERSION="$VERSION" \
            -t $IMAGE_ID:$VERSION \
            .
          
          # Determine publish tags
          if [[ "${{ github.event_name }}" == "release" ]]; then
            # Release: publish version and latest
            docker tag $IMAGE_ID:$VERSION $IMAGE_ID:latest
            echo "Release build: will push tags [$VERSION, latest]"
          else
            # Non-release: publish development
            docker tag $IMAGE_ID:$VERSION $IMAGE_ID:development
            echo "Non-release build: will push tag [development]"
          fi

      - name: Push Docker image
        if: github.event_name != 'pull_request'
        run: |
          IMAGE_ID=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          VERSION="${{ steps.version.outputs.version }}"
          
          echo "Pushing Docker image..."
          echo "Image ID: $IMAGE_ID"
          echo "Version: $VERSION"
          
          if [[ "${{ github.event_name }}" == "release" ]]; then
            # Push version and latest
            docker push $IMAGE_ID:$VERSION
            docker push $IMAGE_ID:latest
          else
            # Push only development
            docker push $IMAGE_ID:development
          fi

      - name: Generate build summary
        run: |
          echo "=== Build Summary ==="
          echo "Repository: ${{ github.repository }}"
          echo "Event: ${{ github.event_name }}"
          echo "Version: ${{ steps.version.outputs.version }}"
          echo "Version Source: ${{ steps.version.outputs.version_source }}"
          echo "Branch: ${{ steps.version.outputs.branch_name }}"
          echo "Build Number: ${{ steps.version.outputs.build_number }}"
          echo "Commit: ${{ github.sha }}"
          echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}"
          echo "===================="

      - name: Comment on PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const { data: comments } = await github.rest.issues.listComments({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
            });
            
            const botComment = comments.find(comment => comment.user.type === 'Bot' && comment.body.includes('Docker build completed'));
            
            const commentBody = `## 🐳 Docker Build Completed
            
            **Build Information:**
            - **Version:** \`${{ steps.version.outputs.version }}\`
            - **Source:** ${{ steps.version.outputs.version_source }}
            - **Branch:** ${{ steps.version.outputs.branch_name }}
            - **Build Number:** ${{ steps.version.outputs.build_number }}
            - **Commit:** \`${{ github.sha }}\`
            
            **Image:** \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}\`
            
            > This is a preview build. The image will be pushed when merged to main.
            
            ---
            *This comment was automatically generated by the Docker build workflow.*`;
            
            if (botComment) {
              await github.rest.issues.updateComment({
                comment_id: botComment.id,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: commentBody,
              });
            } else {
              await github.rest.issues.createComment({
                issue_number: context.issue.number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: commentBody,
              });
            }
