#!/usr/bin/env bash

set -eEo pipefail

SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"

# shellcheck source=ci/docker_commands
source "${SCRIPTPATH}/docker_commands"

IMAGE_FLAVOR=${IMAGE_FLAVOR:-"alpine"}
IMAGE_TAG=${IMAGE_TAG:-""}

tag_latest() {
    if [[ -z "${IS_LATEST}" ]]; then
        return
    fi

    tag "${@}"
}

push_latest() {
    if [[ -z "${IS_LATEST}" ]]; then
        return
    fi

    push "${@}"
}

# Release the helper images.
# The first passed argument will be used as a
# prefix for the image name, which is useful to push do a different registry.
# For example `registry.gitlab.com/gitlab-org/gitlab-runner` and `gitlab`.
# This function will perform all actions needed for pushing except for the
# pushing itself depending on the `PUBLISH_IMAGES` and `PUSH_TO_ECR_PUBLIC` variables
# which is checked inside the `push` function.
# The second argument tells if the push is actually enabled.
# This argument is then forwarded to the `push` function.
release_docker_helper_images() {
    REGISTRY=$1
    PUSH_ENABLED=$2
    FLAVOR=$3
    PREFIX=$4

    helper_image_x86_64="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-${REVISION}"
    helper_image_x86_64_pwsh="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-${REVISION}-pwsh"
    helper_image_x86_64_version="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-${ref_tag}"
    helper_image_x86_64_pwsh_version="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-${ref_tag}-pwsh"
    helper_image_x86_64_latest="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-latest"
    helper_image_x86_64_pwsh_latest="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-latest-pwsh"
    helper_image_arm="${REGISTRY}/gitlab-runner-helper:${PREFIX}arm-${REVISION}"
    helper_image_arm_version="${REGISTRY}/gitlab-runner-helper:${PREFIX}arm-${ref_tag}"
    helper_image_arm_latest="${REGISTRY}/gitlab-runner-helper:${PREFIX}arm-latest"
    helper_image_arm64="${REGISTRY}/gitlab-runner-helper:${PREFIX}arm64-${REVISION}"
    helper_image_arm64_version="${REGISTRY}/gitlab-runner-helper:${PREFIX}arm64-${ref_tag}"
    helper_image_arm64_latest="${REGISTRY}/gitlab-runner-helper:${PREFIX}arm64-latest"
    helper_image_s390x="${REGISTRY}/gitlab-runner-helper:${PREFIX}s390x-${REVISION}"
    helper_image_s390x_version="${REGISTRY}/gitlab-runner-helper:${PREFIX}s390x-${ref_tag}"
    helper_image_s390x_latest="${REGISTRY}/gitlab-runner-helper:${PREFIX}s390x-latest"
    helper_image_ppc64le="${REGISTRY}/gitlab-runner-helper:${PREFIX}ppc64le-${REVISION}"
    helper_image_ppc64le_version="${REGISTRY}/gitlab-runner-helper:${PREFIX}ppc64le-${ref_tag}"
    helper_image_ppc64le_latest="${REGISTRY}/gitlab-runner-helper:${PREFIX}ppc64le-latest"
    helper_image_x86_64_fips="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-${REVISION}"
    helper_image_x86_64_fips_version="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-${ref_tag}"
    helper_image_x86_64_fips_latest="${REGISTRY}/gitlab-runner-helper:${PREFIX}x86_64-latest"

    if [[ "$FLAVOR" == "ubi-fips" ]]; then
        # Special case for FIPS since we don't yet support all the architectures we do for other flavors
        import "out/helper-images/prebuilt-${FLAVOR}-x86_64.tar.xz" "${helper_image_x86_64_fips}" "linux/amd64"
        tag_latest "${helper_image_x86_64_fips}" "${helper_image_x86_64_fips_latest}"
        tag "${helper_image_x86_64_fips}" "${helper_image_x86_64_fips_version}"
        push "${helper_image_x86_64_fips}" "${PUSH_ENABLED}"
        push_latest "${helper_image_x86_64_fips_latest}" "${PUSH_ENABLED}"
        push "${helper_image_x86_64_fips_version}" "${PUSH_ENABLED}"
        return 0
    fi

    import "out/helper-images/prebuilt-${FLAVOR}-x86_64.tar.xz" "${helper_image_x86_64}" "linux/amd64"
    import "out/helper-images/prebuilt-${FLAVOR}-arm.tar.xz" "${helper_image_arm}" "linux/arm/v7"
    import "out/helper-images/prebuilt-${FLAVOR}-arm64.tar.xz" "${helper_image_arm64}" "linux/arm64/v8"
    import "out/helper-images/prebuilt-${FLAVOR}-s390x.tar.xz" "${helper_image_s390x}" "linux/s390x"
    import "out/helper-images/prebuilt-${FLAVOR}-ppc64le.tar.xz" "${helper_image_ppc64le}" "linux/ppc64le"

    tag_latest "${helper_image_x86_64}" "${helper_image_x86_64_latest}"
    tag_latest "${helper_image_arm}" "${helper_image_arm_latest}"
    tag_latest "${helper_image_arm64}" "${helper_image_arm64_latest}"
    tag_latest "${helper_image_s390x}" "${helper_image_s390x_latest}"
    tag_latest "${helper_image_ppc64le}" "${helper_image_ppc64le_latest}"

    tag "${helper_image_x86_64}" "${helper_image_x86_64_version}"
    tag "${helper_image_arm}" "${helper_image_arm_version}"
    tag "${helper_image_arm64}" "${helper_image_arm64_version}"
    tag "${helper_image_s390x}" "${helper_image_s390x_version}"
    tag "${helper_image_ppc64le}" "${helper_image_ppc64le_version}"

    push "${helper_image_x86_64}" "${PUSH_ENABLED}"
    push "${helper_image_arm}" "${PUSH_ENABLED}"
    push "${helper_image_arm64}" "${PUSH_ENABLED}"
    push "${helper_image_s390x}" "${PUSH_ENABLED}"
    push "${helper_image_ppc64le}" "${PUSH_ENABLED}"

    push_latest "${helper_image_x86_64_latest}" "${PUSH_ENABLED}"
    push_latest "${helper_image_arm_latest}" "${PUSH_ENABLED}"
    push_latest "${helper_image_arm64_latest}" "${PUSH_ENABLED}"
    push_latest "${helper_image_s390x_latest}" "${PUSH_ENABLED}"
    push_latest "${helper_image_ppc64le_latest}" "${PUSH_ENABLED}"
    push "${helper_image_x86_64_version}" "${PUSH_ENABLED}"
    push "${helper_image_arm_version}" "${PUSH_ENABLED}"
    push "${helper_image_arm64_version}" "${PUSH_ENABLED}"
    push "${helper_image_s390x_version}" "${PUSH_ENABLED}"
    push "${helper_image_ppc64le_version}" "${PUSH_ENABLED}"

    if [[ "$FLAVOR" != "alpine3.14" ]] && [[ "$FLAVOR" != "alpine3.15" ]] && [[ "$FLAVOR" != "alpine-latest" ]]; then
        # Special case until pwsh adds the alpine 3.14 and 3.15 docker images
        # The two versions can be removed when pwsh adds support for them but the latest flavour must stay
        # As there's no corresponding version for alpine
        # Alpine-latest is a special case pwsh don't support an alpine:latest image
        import "out/helper-images/prebuilt-${FLAVOR}-x86_64-pwsh.tar.xz" "${helper_image_x86_64_pwsh}" "linux/amd64"
        tag_latest "${helper_image_x86_64_pwsh}" "${helper_image_x86_64_pwsh_latest}"
        tag "${helper_image_x86_64_pwsh}" "${helper_image_x86_64_pwsh_version}"
        push "${helper_image_x86_64_pwsh}" "${PUSH_ENABLED}"
        push_latest "${helper_image_x86_64_pwsh_latest}" "${PUSH_ENABLED}"
        push "${helper_image_x86_64_pwsh_version}" "${PUSH_ENABLED}"
    fi
}

# Release helper images
if [[ -n "${CI_REGISTRY_USER}" ]] && [[ -n "${CI_REGISTRY_PASSWORD}" ]] && [[ "${PUBLISH_IMAGES}" == "true" ]]; then
    login "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}"
fi
release_docker_helper_images "${CI_REGISTRY_IMAGE}" "${PUBLISH_IMAGES}" "${IMAGE_FLAVOR}" "${IMAGE_TAG}"
# Docker exits with a 0 code if we weren't logged in previously which makes it fine to run at all times
logout "${CI_REGISTRY}"

if [[ "${PUBLISH_IMAGES}" == "true" ]] && [[ "${PUSH_TO_DOCKER_HUB}" == "true" ]]; then
    login "${DOCKER_HUB_USER}" "${DOCKER_HUB_PASSWORD}"
fi

release_docker_helper_images "${DOCKER_HUB_NAMESPACE}" "${PUBLISH_IMAGES}" "${IMAGE_FLAVOR}" "${IMAGE_TAG}"
logout

if [[ "${PUBLISH_IMAGES}" == "true" ]] && [[ "${PUSH_TO_ECR_PUBLIC}" == "true" ]]; then
    ECR_PUBLIC_REGISTRY_PASSWORD=$(aws --region us-east-1 ecr-public get-login-password)

    login "${ECR_PUBLIC_USER}" "${ECR_PUBLIC_REGISTRY_PASSWORD}" "${ECR_PUBLIC_REGISTRY}"
fi
release_docker_helper_images "${ECR_PUBLIC_REGISTRY}" "${PUSH_TO_ECR_PUBLIC}" "${IMAGE_FLAVOR}" "${IMAGE_TAG}"
logout "${ECR_PUBLIC_REGISTRY}"
