name: Auth Service Build and Deploy

on:
  push:
    branches: [ "main" ]
    paths:
      - 'src/main/go/net/eagle0/authservice/**'
      - 'src/main/go/net/eagle0/authcli/**'
      - 'src/main/protobuf/net/eagle0/eagle/api/auth.proto'
      - 'src/main/protobuf/net/eagle0/eagle/api/admin/**'
      - 'src/main/protobuf/net/eagle0/eagle/internal/auth_internal.proto'
      - 'src/main/resources/net/eagle0/attributions.json'
      - 'ci/BUILD.bazel'
      - '.bazelrc'
      - '.github/workflows/auth_build.yml'
  workflow_dispatch:
    inputs:
      push_images:
        description: 'Push images to container registry'
        required: true
        default: 'false'
        type: boolean

permissions:
  contents: read

jobs:
  build-auth:
    runs-on: [self-hosted, bazel]
    outputs:
      image_tag: ${{ steps.push-auth.outputs.image_tag }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          lfs: false

      - name: Build Auth Server Docker image
        id: build-auth
        run: |
          set -ex

          # Build auth server image (Go binary has explicit goos/goarch in BUILD.bazel)
          # --stamp is needed for authservice x_defs (git commit, build time)
          bazel build --stamp //ci:auth_server_image

          # Save the resolved path before any other bazel command changes bazel-bin symlink
          IMAGE_PATH=$(readlink -f bazel-bin/ci/auth_server_image)
          echo "Image path: $IMAGE_PATH"
          echo "image_path=$IMAGE_PATH" >> $GITHUB_OUTPUT

      - name: Login to DigitalOcean Container Registry
        if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_images == 'true')
        env:
          DO_TOKEN: ${{ secrets.DO_REGISTRY_TOKEN }}
        run: |
          mkdir -p ~/.docker
          AUTH=$(echo -n "${DO_TOKEN}:${DO_TOKEN}" | base64)
          echo "{\"auths\":{\"registry.digitalocean.com\":{\"auth\":\"${AUTH}\"}}}" > ~/.docker/config.json
          mkdir -p .docker
          cp ~/.docker/config.json .docker/

      - name: Push Auth image to DO registry
        id: push-auth
        if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_images == 'true')
        env:
          DOCKER_CONFIG: ${{ github.workspace }}/.docker
        run: |
          set -ex

          AUTH_IMAGE="${{ steps.build-auth.outputs.image_path }}"
          echo "Using Auth image: $AUTH_IMAGE"

          if [ -z "$AUTH_IMAGE" ] || [ ! -d "$AUTH_IMAGE" ]; then
            echo "ERROR: Auth image not found at: $AUTH_IMAGE"
            exit 1
          fi

          # Build the push target to get crane in runfiles
          bazel build //ci:auth_server_push

          # Find crane binary in runfiles (path varies by Bazel version)
          RUNFILES="bazel-bin/ci/push_auth_server_push.sh.runfiles"
          CRANE=$(find "$RUNFILES" -path "*darwin*" -name crane 2>/dev/null | head -1)
          if [ -z "$CRANE" ] || [ ! -x "$CRANE" ]; then
            echo "ERROR: crane not found in runfiles"
            find "$RUNFILES" -name crane 2>/dev/null || echo "No crane found at all"
            exit 1
          fi
          echo "Using crane: $CRANE"

          # Push with SHA tag
          GIT_SHA=$(git rev-parse --short=8 HEAD)
          IMAGE_TAG="registry.digitalocean.com/eagle0/auth-server:${GIT_SHA}"
          echo "Pushing auth image: $IMAGE_TAG"
          $CRANE push "$AUTH_IMAGE" "$IMAGE_TAG"

          # Output the full image tag for deploy step
          echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT

          # Also update :latest for convenience
          echo "Copying to :latest tag"
          $CRANE copy "$IMAGE_TAG" "registry.digitalocean.com/eagle0/auth-server:latest"

  deploy:
    runs-on: ubuntu-latest
    needs: [build-auth]
    if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_images == 'true')
    environment: production
    env:
      AUTH_IMAGE: ${{ needs.build-auth.outputs.image_tag }}
      DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
      DISCORD_CLIENT_SECRET: ${{ secrets.DISCORD_CLIENT_SECRET }}
      GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
      GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
      GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
      GH_OAUTH_CLIENT_SECRET: ${{ secrets.GH_OAUTH_CLIENT_SECRET }}
      APPLE_SIGNIN_CLIENT_ID: ${{ secrets.APPLE_SIGNIN_CLIENT_ID }}
      APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
      APPLE_SIGNIN_KEY_ID: ${{ secrets.APPLE_SIGNIN_KEY_ID }}
      APPLE_SIGNIN_PRIVATE_KEY: ${{ secrets.APPLE_SIGNIN_PRIVATE_KEY }}
      TWITCH_CLIENT_ID: ${{ secrets.TWITCH_CLIENT_ID }}
      TWITCH_CLIENT_SECRET: ${{ secrets.TWITCH_CLIENT_SECRET }}
      JWT_PRIVATE_KEY: ${{ secrets.JWT_PRIVATE_KEY }}
      FASTMAIL_API_TOKEN: ${{ secrets.FASTMAIL_API_TOKEN }}
      FASTMAIL_FROM_EMAIL: ${{ secrets.FASTMAIL_FROM_EMAIL }}
      FASTMAIL_FROM_NAME: ${{ secrets.FASTMAIL_FROM_NAME }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Deploy auth service to production
        uses: appleboy/ssh-action@v1.2.5
        with:
          host: ${{ secrets.DO_DROPLET_IP }}
          username: deploy
          key: ${{ secrets.DO_SSH_KEY }}
          script_stop: true
          envs: AUTH_IMAGE,DISCORD_CLIENT_ID,DISCORD_CLIENT_SECRET,GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GH_OAUTH_CLIENT_ID,GH_OAUTH_CLIENT_SECRET,APPLE_SIGNIN_CLIENT_ID,APPLE_TEAM_ID,APPLE_SIGNIN_KEY_ID,APPLE_SIGNIN_PRIVATE_KEY,TWITCH_CLIENT_ID,TWITCH_CLIENT_SECRET,JWT_PRIVATE_KEY,FASTMAIL_API_TOKEN,FASTMAIL_FROM_EMAIL,FASTMAIL_FROM_NAME
          script: |
            set -x
            cd /opt/eagle0

            # Export env vars for docker compose (appleboy/ssh-action sets them but doesn't export)
            export AUTH_IMAGE="${AUTH_IMAGE}"
            export DISCORD_CLIENT_ID="${DISCORD_CLIENT_ID}"
            export DISCORD_CLIENT_SECRET="${DISCORD_CLIENT_SECRET}"
            export GOOGLE_CLIENT_ID="${GOOGLE_CLIENT_ID}"
            export GOOGLE_CLIENT_SECRET="${GOOGLE_CLIENT_SECRET}"
            export GH_OAUTH_CLIENT_ID="${GH_OAUTH_CLIENT_ID}"
            export GH_OAUTH_CLIENT_SECRET="${GH_OAUTH_CLIENT_SECRET}"
            export APPLE_SIGNIN_CLIENT_ID="${APPLE_SIGNIN_CLIENT_ID}"
            export APPLE_TEAM_ID="${APPLE_TEAM_ID}"
            export APPLE_SIGNIN_KEY_ID="${APPLE_SIGNIN_KEY_ID}"
            export APPLE_SIGNIN_PRIVATE_KEY="${APPLE_SIGNIN_PRIVATE_KEY}"
            export TWITCH_CLIENT_ID="${TWITCH_CLIENT_ID}"
            export TWITCH_CLIENT_SECRET="${TWITCH_CLIENT_SECRET}"
            export JWT_PRIVATE_KEY="${JWT_PRIVATE_KEY}"
            export FASTMAIL_API_TOKEN="${FASTMAIL_API_TOKEN}"
            export FASTMAIL_FROM_EMAIL="${FASTMAIL_FROM_EMAIL}"
            export FASTMAIL_FROM_NAME="${FASTMAIL_FROM_NAME}"

            # Login to registry
            echo "${{ secrets.DO_REGISTRY_TOKEN }}" | docker login registry.digitalocean.com -u "${{ secrets.DO_REGISTRY_TOKEN }}" --password-stdin

            echo "Deploying auth service: $AUTH_IMAGE"

            # Pull the image directly (docker is already logged in)
            echo "Pulling Auth image..."
            docker pull "${AUTH_IMAGE}" || { echo "ERROR: Failed to pull auth image"; exit 1; }

            # Tag as :latest locally so any fallback uses correct image
            docker tag "${AUTH_IMAGE}" registry.digitalocean.com/eagle0/auth-server:latest

            # Debug: check environment and .env file
            echo "DEBUG: AUTH_IMAGE=$AUTH_IMAGE"
            env | grep AUTH || echo "AUTH_IMAGE not in env output"
            if [ -f .env ]; then
              echo "DEBUG: .env file contents related to AUTH:"
              grep AUTH .env || echo "No AUTH in .env"
            fi

            # Recreate auth container - pass AUTH_IMAGE explicitly on command line
            AUTH_IMAGE="${AUTH_IMAGE}" docker compose -f docker-compose.prod.yml up -d --no-deps --force-recreate auth

            # Wait for health check
            sleep 5

            # Verify container is using the correct image
            # Note: docker-compose may use :latest tag (which we tagged to the correct image)
            echo "=== Verifying auth container image ==="
            RUNNING_IMAGE=$(docker inspect auth-server --format '{{.Config.Image}}')
            RUNNING_DIGEST=$(docker inspect auth-server --format '{{.Image}}')
            EXPECTED_DIGEST=$(docker inspect "${AUTH_IMAGE}" --format '{{.Id}}')
            echo "Expected image: ${AUTH_IMAGE}"
            echo "Running image:  ${RUNNING_IMAGE}"
            echo "Expected digest: ${EXPECTED_DIGEST}"
            echo "Running digest:  ${RUNNING_DIGEST}"

            if [ "$RUNNING_DIGEST" != "$EXPECTED_DIGEST" ]; then
              echo "ERROR: Container is running wrong image!"
              exit 1
            fi
            echo "Image digests match - correct image is running"

            # Show container status
            docker compose -f docker-compose.prod.yml ps auth

            # Cleanup old images
            docker image prune -f
