#!/usr/bin/env bash
#
# This script builds and pushes cross-platform Docker containers. Maintainers
# should *not* run this locally since it pushes the containers.
#
# This script expects to be run from the repo root and has checks for running
# from a GitHub Actions trigger.
set -euxo pipefail

# Environment variables used throughout this script. These must be set
# otherwise bash will fail with an "unbound variable" error because of the `set
# -u` flag on the above line.
#
# If the environment variables are unset, the variables below default to an
# empty string.
export TARGET_CONTAINER=${1:-}
PUSH_ALLOY_IMAGE=${PUSH_ALLOY_IMAGE:-}
export GITHUB_REF_TYPE=${GITHUB_REF_TYPE:-}
GITHUB_PR_NUMBER=${GITHUB_PR_NUMBER:-}

if [ "$GITHUB_REF_TYPE" = "tag" ]; then
  export GITHUB_TAG="$GITHUB_REF_NAME"
else
  export GITHUB_TAG=""
fi

DOCKER_FLAGS=""
if [[ $PUSH_ALLOY_IMAGE == "true"  ]]; then
	DOCKER_FLAGS="--push"
fi

export RELEASE_ALLOY_IMAGE=grafana/alloy
export DEVEL_ALLOY_IMAGE=grafana/alloy-dev

# We need to determine what version to assign to built binaries. 
# If containers are being built from a GitHub Actions tag trigger, 
# we force the version to come from the GitHub Actions tag name.
#
# Otherwise, we use the ./tools/image-tag script to determine the version.
if [ -n "$GITHUB_TAG" ]; then
  VERSION=$GITHUB_TAG
else
  # NOTE(rfratto): Do not use ./tools/image-tag-docker here, which doesn't
  # produce valid semver.
  VERSION=$(./tools/image-tag)
fi

# DEFAULT_LATEST is the default tag to use for the "latest" tag.
DEFAULT_LATEST=latest
BORINGCRYPTO_LATEST=boringcrypto

# The TAG_VERSION is the version to use for the Docker tag. It is sanitized to
# force it to be a valid Docker tag name (primarily by removing the +
# characters that may have been emitted by ./tools/image-tag).
TAG_VERSION=${VERSION//+/-}

# We also need to know which "branch tag" to update. Branch tags are used as a
# secondary tag for Docker containers. The branch tag is "latest" when being
# tagged from a stable release (i.e., not a release candidate) or when building
# a dev image.
#
# If we're not running from GitHub Actions, we'll set the branch tag to match the
# version. This effectively acts as a no-op because it will tag the same Docker
# image twice.
if [[ -n "$GITHUB_TAG" && "$GITHUB_TAG" != *"-rc."* ]] || [[ "$TARGET_CONTAINER" == *"-devel"* ]]; then
  BRANCH_TAG=latest
else
  BRANCH_TAG=$TAG_VERSION
fi

# Build all of our images.

export BUILD_PLATFORMS=linux/amd64,linux/arm64,linux/ppc64le,linux/s390x
export BUILD_PLATFORMS_BORINGCRYPTO=linux/amd64,linux/arm64

case "$TARGET_CONTAINER" in
  alloy)
    docker buildx build $DOCKER_FLAGS        \
      --platform $BUILD_PLATFORMS            \
      --build-arg RELEASE_BUILD=1            \
      --build-arg VERSION="$VERSION"         \
      -t "$RELEASE_ALLOY_IMAGE:$TAG_VERSION" \
      -t "$RELEASE_ALLOY_IMAGE:$BRANCH_TAG"  \
      -f Dockerfile                          \
      .
    ;;

  alloy-boringcrypto)
    if [[ "$BRANCH_TAG" == "$DEFAULT_LATEST" ]]; then
      BRANCH_TAG=$BORINGCRYPTO_LATEST
    fi

    docker buildx build $DOCKER_FLAGS                     \
      --platform $BUILD_PLATFORMS_BORINGCRYPTO            \
      --build-arg RELEASE_BUILD=1                         \
      --build-arg VERSION="$VERSION"                      \
      --build-arg GOEXPERIMENT=boringcrypto               \
      -t "$RELEASE_ALLOY_IMAGE:$TAG_VERSION-boringcrypto" \
      -t "$RELEASE_ALLOY_IMAGE:$BRANCH_TAG"               \
      -f Dockerfile                                       \
      .
    ;;

  alloy-devel)
    docker buildx build $DOCKER_FLAGS      \
      --platform $BUILD_PLATFORMS          \
      --build-arg RELEASE_BUILD=1          \
      --build-arg VERSION="$VERSION"       \
      -t "$DEVEL_ALLOY_IMAGE:$TAG_VERSION" \
      -t "$DEVEL_ALLOY_IMAGE:$BRANCH_TAG"  \
      -f Dockerfile                        \
      .
    ;;

  alloy-devel-boringcrypto)
    if [[ "$BRANCH_TAG" == "$DEFAULT_LATEST" ]]; then
      BRANCH_TAG=$BORINGCRYPTO_LATEST
    fi

    docker buildx build $DOCKER_FLAGS                   \
      --platform $BUILD_PLATFORMS_BORINGCRYPTO          \
      --build-arg RELEASE_BUILD=1                       \
      --build-arg VERSION="$VERSION"                    \
      --build-arg GOEXPERIMENT=boringcrypto             \
      -t "$DEVEL_ALLOY_IMAGE:$TAG_VERSION-boringcrypto" \
      -t "$DEVEL_ALLOY_IMAGE:$BRANCH_TAG"               \
      -f Dockerfile                                     \
      .
    ;;

  alloy-devel-pr)
	TAG="pr-${GITHUB_PR_NUMBER}-${TAG_VERSION}"

    docker buildx build $DOCKER_FLAGS      \
      --platform $BUILD_PLATFORMS          \
      --build-arg RELEASE_BUILD=1          \
      --build-arg VERSION="$VERSION"       \
      -t "$DEVEL_ALLOY_IMAGE:$TAG" \
      -f Dockerfile                        \
      .
    ;;

  alloy-devel-boringcrypto-pr)
	TAG="pr-${GITHUB_PR_NUMBER}-${TAG_VERSION}"

    docker buildx build $DOCKER_FLAGS                   \
      --platform $BUILD_PLATFORMS_BORINGCRYPTO          \
      --build-arg RELEASE_BUILD=1                       \
      --build-arg VERSION="$VERSION"                    \
      --build-arg GOEXPERIMENT=boringcrypto             \
      -t "$DEVEL_ALLOY_IMAGE:$TAG-boringcrypto" \
      -f Dockerfile                                     \
      .
    ;;

  *)
    echo "Usage: $0 alloy|alloy-boringcrypto|alloy-devel|alloy-devel-boringcrypto|alloy-devel-pr|alloy-devel-boringcrypto-pr"
    exit 1
    ;;
esac

