name: Docker

# Runs only after the CI workflow completes, so an image is never pushed for a commit
# whose formatting, lint, build, or tests failed.
on:
  workflow_run:
    workflows: ["CI"]
    types: [completed]
    branches: [master]
  workflow_dispatch:

permissions:
  contents: read
  packages: write

env:
  IMAGE: ghcr.io/huebyte/echohub-server

jobs:
  docker:
    name: Build & Push Docker Image
    # Proceed only for a successful CI run on a master push, or a manual dispatch.
    if: >-
      github.event_name == 'workflow_dispatch' ||
      (github.event.workflow_run.conclusion == 'success' &&
       github.event.workflow_run.event == 'push' &&
       github.event.workflow_run.head_branch == 'master')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          # The exact commit CI tested (workflow_run), or the current tip (manual dispatch).
          ref: ${{ github.event.workflow_run.head_sha || github.sha }}

      - name: Check for src/ changes
        id: changes
        run: |
          if git rev-parse HEAD~1 >/dev/null 2>&1; then
            CHANGED=$(git diff --name-only HEAD~1 HEAD -- 'src/' | wc -l)
          else
            CHANGED=1
          fi
          [ "$CHANGED" -gt 0 ] && echo "src_changed=true" >> "$GITHUB_OUTPUT" || echo "src_changed=false" >> "$GITHUB_OUTPUT"

      - name: Read version
        if: steps.changes.outputs.src_changed == 'true'
        id: version
        run: |
          VERSION=$(grep -oP '(?<=<Version>)[^<]+' src/Directory.Build.props)
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"
          echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"

      - name: Check if image tag exists
        if: steps.changes.outputs.src_changed == 'true'
        id: check_image
        run: |
          TAG="${{ steps.version.outputs.tag }}"
          if docker manifest inspect "${{ env.IMAGE }}:${TAG}" &>/dev/null; then
            echo "exists=true" >> "$GITHUB_OUTPUT"
          else
            echo "exists=false" >> "$GITHUB_OUTPUT"
          fi
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Set up QEMU
        if: steps.changes.outputs.src_changed == 'true' && steps.check_image.outputs.exists == 'false'
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        if: steps.changes.outputs.src_changed == 'true' && steps.check_image.outputs.exists == 'false'
        uses: docker/setup-buildx-action@v3

      - name: Log in to GHCR
        if: steps.changes.outputs.src_changed == 'true' && steps.check_image.outputs.exists == 'false'
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        if: steps.changes.outputs.src_changed == 'true' && steps.check_image.outputs.exists == 'false'
        uses: docker/build-push-action@v6
        with:
          context: ./src
          file: ./src/EchoHub.Server/Dockerfile
          platforms: linux/amd64,linux/arm64
          push: true
          tags: |
            ${{ env.IMAGE }}:latest
            ${{ env.IMAGE }}:${{ steps.version.outputs.tag }}
          labels: |
            org.opencontainers.image.title=EchoHub Server
            org.opencontainers.image.description=Self-hosted IRC-style chat server
            org.opencontainers.image.version=${{ steps.version.outputs.version }}
            org.opencontainers.image.source=https://github.com/${{ github.repository }}

      - name: Skip notice
        if: steps.changes.outputs.src_changed != 'true' || steps.check_image.outputs.exists == 'true'
        run: echo "⏭️ Skipped — no src/ changes or image tag already exists."
