name: docker
on:
  push:
    branches: [main]
    tags: ['v*']
    paths-ignore:
      - '**/*.md'
      - '**/*.txt'
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      mariadb:
        image: mariadb:11
        env:
          MARIADB_DATABASE: jellomator_test
          MARIADB_USER: jellomator
          MARIADB_PASSWORD: jellomator
          MARIADB_ROOT_PASSWORD: root
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mariadb-admin ping -h 127.0.0.1 -uroot -proot"
          --health-interval=5s
          --health-timeout=5s
          --health-retries=20
    env:
      DB_HOST: mariadb
      DB_PORT: "3306"
      DB_USER: jellomator
      DB_PASSWORD: jellomator
      DB_NAME: jellomator_test
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - name: Install Python dependencies
        run: pip install -r backend/requirements-dev.txt
      - name: Run backend tests
        run: pytest -q

  build-and-push:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ${{ secrets.REGISTRY }}
          username: ${{ secrets.REGISTRY_USERNAME }}
          password: ${{ secrets.REGISTRY_PASSWORD }}
      - name: Resolve image metadata
        id: meta
        shell: bash
        run: |
          set -euo pipefail
          owner="${{ github.repository_owner }}"
          repo="${{ github.event.repository.name }}"
          image="${{ secrets.IMAGE_NAME }}"
          if [ -z "$image" ]; then
            echo "::error::IMAGE_NAME secret is empty."
            exit 1
          fi
          {
            echo "owner=$owner"
            echo "repo=$repo"
            echo "image=$image"
          } >> "$GITHUB_OUTPUT"
      - uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile
          push: true
          build-args: |
            VCS_REF=${{ github.sha }}
            VCS_URL=${{ github.server_url }}/${{ github.repository }}
          tags: |
            ${{ secrets.REGISTRY }}/${{ secrets.IMAGE_NAME }}:latest
            ${{ secrets.REGISTRY }}/${{ secrets.IMAGE_NAME }}:${{ github.sha }}
      - name: Link package to repository
        shell: bash
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
          PACKAGE_OWNER: ${{ steps.meta.outputs.owner }}
          PACKAGE_NAME: ${{ steps.meta.outputs.repo }}
          REPO_NAME: ${{ steps.meta.outputs.repo }}
        run: |
          set -euo pipefail
          token="${REGISTRY_PASSWORD:-${REGISTRY_TOKEN:-}}"
          if [ -z "$token" ]; then
            echo "::error::Registry token/password is empty. Set REGISTRY_PASSWORD or REGISTRY_TOKEN."
            exit 1
          fi
          python3 - <<'PY'
          import json
          import os
          import sys
          import urllib.error
          import urllib.parse
          import urllib.request

          owner = os.environ["PACKAGE_OWNER"]
          package = os.environ["PACKAGE_NAME"]
          repo = os.environ["REPO_NAME"]
          token = os.environ["REGISTRY_PASSWORD"] or os.environ["REGISTRY_TOKEN"]
          base = "https://gitea.reversed.dev/api/v1"
          headers = {
              "Authorization": f"token {token}",
              "Accept": "application/json",
          }

          latest_url = f"{base}/packages/{urllib.parse.quote(owner)}/container/{urllib.parse.quote(package)}/-/latest"
          req = urllib.request.Request(latest_url, headers=headers)
          with urllib.request.urlopen(req) as resp:
              current = json.load(resp)

          linked_repo = (current.get("repository") or {}).get("name")
          if linked_repo == repo:
              print(f"package already linked to {owner}/{repo}")
              sys.exit(0)

          link_url = f"{base}/packages/{urllib.parse.quote(owner)}/container/{urllib.parse.quote(package)}/-/link/{urllib.parse.quote(repo)}"
          link_req = urllib.request.Request(link_url, data=b"", method="POST", headers=headers)
          try:
              with urllib.request.urlopen(link_req) as resp:
                  print(f"linked package to {owner}/{repo}, status={resp.status}")
          except urllib.error.HTTPError as exc:
              body = exc.read().decode(errors="replace")
              print(f"link failed: status={exc.code} body={body}")
              raise
          PY
