#!/usr/bin/env bash

set -euox pipefail

project_name=${ZOOX_PROJECT_NAME}

should_docker_login="false"
# This can be configured in the `env` object in `ci.yaml` files.
if [[ -n ${DOCKER_REGISTRY:-} ]]; then
    docker_registry_host="${DOCKER_REGISTRY}.docker.zooxlabs.com"
    should_docker_login="true"
else
    docker_registry_host="docker-registry.zooxlabs.com"
fi
docker_image_name="${project_name}"
docker_sock=${DOCKER_SOCK:-''}

# Automatically set docker sock to default path if DOCKER_SOCK is not provided and default docker sock exists
if [[ -z "${docker_sock}" && -e "/var/run/docker.sock" ]]; then
    docker_sock="unix:///var/run/docker.sock"
else
    docker_sock=${DOCKER_SOCK:-"unix:///var/run/ci_docker.sock"}
fi

docker_command="docker --host ${docker_sock}"

pypi_repo_url=${PYPI_REPOSITORY_URL:-"https://pypi.zooxlabs.com/pypi"}
pypi_username=${PYPI_USERNAME:-zoox}
pypi_password=${PYPI_PASSWORD:-zoox}
pypi_index_url=${PYPI_INDEX_URL:-"https://pypi.zooxlabs.com/simple/"}

qualifier=""
docker_qualifier=""
twine_extra_args="--skip-existing"

git_sha=$(git rev-parse HEAD)
git_tag=$(git tag --points-at "${git_sha}")
should_push_new_docker_tag="false"
if [[ "${git_tag}" =~ "${project_name}__" ]]; then
  should_push_new_docker_tag="true"
fi

current_git_branch=${ZOOX_BRANCH_NAME:-""}
if [[ -z "${current_git_branch}" ]]; then
    current_git_branch=$(git rev-parse --abbrev-ref HEAD)
fi
current_git_branch=$(echo "${current_git_branch}" | sed "s|/|_|g" | sed "s|--*|-|g")

build_number=$(date +%s)
# If the git sha has tags associated with it then publish the version as released (empty qualifier) and also add skip
# flags to avoid build failures due to publish errors during repeated builds in CI (as the released package may already
# exist from a previous build). If the branch is master and has no tags then mark the package as dev build otherwise
# it must be a non master branch so mark the build with branch name.
if [[ $should_push_new_docker_tag == "true" ]]; then
    qualifier=""
    docker_qualifier=""
elif [[ "${current_git_branch}" == "master" ]]; then
    qualifier=".dev${build_number}"
    docker_qualifier="-dev"
else
    qualifier=".${build_number}+${current_git_branch}"  # Use '+' to comply with PEP440
    docker_qualifier="-${current_git_branch}"
fi

# Copy everything into a temp directory so that we're not directly modifying source.
temp_build_dir=$(mktemp --directory)
cp -R . $temp_build_dir
# Create an environment variable for the git root before changing directory
# to the temp dir, so that the setuptools can know where is the git root
export CI_PYTHON_GIT_ROOT=$(git rev-parse --show-toplevel)
cd $temp_build_dir

# Remove the old build and dist folder
rm -rf build dist

# Get the unqualified version and set the docker variables.
# Run this to make sure that test eggs are created and don't interfere with commands.
python setup.py --help &> /dev/null
setup_version=$(python setup.py --version 2> /dev/null)
image_version="${setup_version}${docker_qualifier}"
image_name="${docker_registry_host}/${docker_image_name}:${image_version}"
latest_image_name="${docker_registry_host}/${docker_image_name}:latest"

# Update the qualifier
# First check that what we're going to update actually exists,
# otherwise we run the risk of not actually updating the qualifier
# and tox will build a unqualified (i.e. release!) version.
qualifier_match_string="^__QUALIFIER__ *= *[\"\'][\"\']$"
if ! grep --quiet "${qualifier_match_string}" setup.py; then
    echo "Invalid or missing __QUALIFIER__ set in setup.py"
    exit 1
fi
sed --in-place "s|${qualifier_match_string}|__QUALIFIER__ = \"${qualifier}\"|g" setup.py

# Get the package full name.
setup_qualified_version=$(python setup.py --version 2> /dev/null| sed "s/[/_]/-/g")
setup_repo_name=$(python setup.py --name 2> /dev/null)

# Make the build.
tox -i "${pypi_index_url}"

# Upload the package if the branch is not HEAD or qualifier is empty.
# Create the docker image and push it if the branch is not HEAD or qualifier is empty. Also, push it as `latest` tag if
# the current branch is master.
if [[ "${current_git_branch}" != "HEAD" || -z "${qualifier}" ]]; then
    twine upload dist/* --repository-url "${pypi_repo_url}"  --username "${pypi_username}" --password "${pypi_password}" ${twine_extra_args}

    ${docker_command} build --pull --tag "${image_name}" --build-arg PACKAGE_NAME="${setup_repo_name}==${setup_qualified_version}" .

    if [[
        $should_docker_login == "true" &&
        (
            $should_push_new_docker_tag == "true" ||
            $current_git_branch == "master"
        )
    ]]; then
        echo Logging into $docker_registry_host
        (
            # Disable command logging to prevent the artifactory token from
            # being printed in plain text.
            set +x
            # This password is provided by the custom jobs framework.
            ${docker_command} login "$docker_registry_host" \
                --username cinder \
                --password "$ARTIFACTORY_DOCKER_TOKEN"
        )
    fi

    if [[ "$should_push_new_docker_tag" == "true" ]]; then
        ${docker_command} push "${image_name}"
    fi

    if [[ "${current_git_branch}" == "master" ]]; then
        ${docker_command} tag "${image_name}" "${latest_image_name}"
        ${docker_command} push "${latest_image_name}"
    fi
fi
