#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
REGISTRY=${REGISTRY:-registry.bstein.dev}
IMAGE_PREFIX=${IMAGE_PREFIX:-${REGISTRY}/lesavka}
IMAGE_TAG=${IMAGE_TAG:-$(git -C "${ROOT_DIR}" rev-parse --short HEAD)}
PUSH_IMAGES=${PUSH_IMAGES:-1}
PLATFORMS=${PLATFORMS:-linux/amd64,linux/arm64}

should_push() {
  case "${PUSH_IMAGES}" in
    1|true|TRUE|yes|YES) return 0 ;;
    *) return 1 ;;
  esac
}

build_with_buildx() {
  local dockerfile=$1
  local image=$2
  local platform_args=()

  if should_push; then
    platform_args=(--platform "${PLATFORMS}")
    docker buildx build \
      "${platform_args[@]}" \
      -f "${dockerfile}" \
      -t "${image}:${IMAGE_TAG}" \
      -t "${image}:latest" \
      --push \
      "${ROOT_DIR}"
  else
    # buildx cannot `--load` a manifest list, so load the host platform only.
    local host_platform
    host_platform="$(docker version --format '{{.Server.Os}}/{{.Server.Arch}}' 2>/dev/null || echo linux/amd64)"
    platform_args=(--platform "${host_platform}")
    docker buildx build \
      "${platform_args[@]}" \
      -f "${dockerfile}" \
      -t "${image}:${IMAGE_TAG}" \
      -t "${image}:latest" \
      --load \
      "${ROOT_DIR}"
  fi
}

build_with_docker() {
  local dockerfile=$1
  local image=$2

  docker build \
    -f "${dockerfile}" \
    -t "${image}:${IMAGE_TAG}" \
    -t "${image}:latest" \
    "${ROOT_DIR}"

  if should_push; then
    docker push "${image}:${IMAGE_TAG}"
    docker push "${image}:latest"
  fi
}

if docker buildx version >/dev/null 2>&1; then
  build_with_buildx "${ROOT_DIR}/docker/server.Dockerfile" "${IMAGE_PREFIX}/server"
  build_with_buildx "${ROOT_DIR}/docker/client.Dockerfile" "${IMAGE_PREFIX}/client"
else
  build_with_docker "${ROOT_DIR}/docker/server.Dockerfile" "${IMAGE_PREFIX}/server"
  build_with_docker "${ROOT_DIR}/docker/client.Dockerfile" "${IMAGE_PREFIX}/client"
fi
