name: Build and Push Multi-Arch Docker Images

on:
  push:
    branches:
      - main
    tags:
      - 'v*'
  pull_request:
    branches:
      - main
  workflow_dispatch:

env:
  REGISTRY: ghcr.io

jobs:
  build-amd64:
    name: Build ${{ matrix.service }} (amd64)
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    strategy:
      fail-fast: false
      matrix:
        service:
          - control-panel-backend
          - control-panel-frontend
          - tenant-backend
          - tenant-app
          - resource-cluster
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

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

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

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.service }}
          tags: |
            type=ref,event=branch,suffix=-amd64
            type=ref,event=pr,suffix=-amd64
            type=semver,pattern={{version}},suffix=-amd64
            type=sha,prefix={{branch}}-,suffix=-amd64

      - name: Build and push (amd64)
        uses: docker/build-push-action@v5
        with:
          context: apps/${{ matrix.service }}
          file: apps/${{ matrix.service }}/Dockerfile
          platforms: linux/amd64
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha,scope=${{ matrix.service }}-amd64
          cache-to: type=gha,mode=max,scope=${{ matrix.service }}-amd64
          provenance: false

  build-arm64:
    name: Build ${{ matrix.service }} (arm64)
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    strategy:
      fail-fast: false
      matrix:
        service:
          - control-panel-backend
          - control-panel-frontend
          - tenant-backend
          - tenant-app
          - resource-cluster
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
        with:
          platforms: arm64

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

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

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.service }}
          tags: |
            type=ref,event=branch,suffix=-arm64
            type=ref,event=pr,suffix=-arm64
            type=semver,pattern={{version}},suffix=-arm64
            type=sha,prefix={{branch}}-,suffix=-arm64

      - name: Build and push (arm64)
        uses: docker/build-push-action@v5
        with:
          context: apps/${{ matrix.service }}
          file: apps/${{ matrix.service }}/Dockerfile
          platforms: linux/arm64
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha,scope=${{ matrix.service }}-arm64
          cache-to: type=gha,mode=max,scope=${{ matrix.service }}-arm64
          provenance: false

  create-manifest:
    name: Create multi-arch manifest for ${{ matrix.service }}
    runs-on: ubuntu-latest
    needs: [build-amd64, build-arm64]
    if: github.event_name != 'pull_request'
    permissions:
      contents: read
      packages: write
    strategy:
      fail-fast: false
      matrix:
        service:
          - control-panel-backend
          - control-panel-frontend
          - tenant-backend
          - tenant-app
          - resource-cluster
    steps:
      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}

      - name: Determine tags
        id: tags
        run: |
          # Get branch/tag name
          if [[ "${{ github.ref }}" == refs/tags/* ]]; then
            TAG="${{ github.ref_name }}"
          elif [[ "${{ github.ref }}" == refs/heads/* ]]; then
            TAG="${GITHUB_REF#refs/heads/}"
          else
            TAG="${{ github.sha }}"
          fi
          echo "tag=${TAG}" >> $GITHUB_OUTPUT

          # Set latest tag only for main branch
          if [[ "${TAG}" == "main" ]]; then
            echo "latest=true" >> $GITHUB_OUTPUT
          else
            echo "latest=false" >> $GITHUB_OUTPUT
          fi

      - name: Create and push multi-arch manifest
        run: |
          # Lowercase the repository name (Docker requires lowercase)
          REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
          IMAGE="${{ env.REGISTRY }}/${REPO_LOWER}/${{ matrix.service }}"
          TAG="${{ steps.tags.outputs.tag }}"

          # Create manifest from arch-specific images
          docker buildx imagetools create -t ${IMAGE}:${TAG} \
            ${IMAGE}:${TAG}-amd64 \
            ${IMAGE}:${TAG}-arm64

          # Also tag as latest if on main
          if [[ "${{ steps.tags.outputs.latest }}" == "true" ]]; then
            docker buildx imagetools create -t ${IMAGE}:latest \
              ${IMAGE}:${TAG}-amd64 \
              ${IMAGE}:${TAG}-arm64
          fi

          # If this is a version tag, also create version manifest
          if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
            VERSION="${{ github.ref_name }}"
            docker buildx imagetools create -t ${IMAGE}:${VERSION} \
              ${IMAGE}:${TAG}-amd64 \
              ${IMAGE}:${TAG}-arm64
          fi
