#!/usr/bin/env bash
set -e

source $(dirname "$0")/common.sh

KUBEVIRT_BUILDER_IMAGE="kubevirt/builder@sha256:e6a76ec71f2de87c3bc648bae87ab43a113540bf57da69f07f76bd0edfd500ab"

DOCKER_DIR=${KUBEVIRT_DIR}/hack/kubevirt-builder

SYNC_OUT=${SYNC_OUT:-true}

BUILDER=${job_prefix}

SYNC_VENDOR=${SYNC_VENDOR:-false}

TEMPFILE=".rsynctemp"

# Be less verbose with bazel
# For ppc64le the bazel server seems to be running out of memory in the Travis CI, so forcing no concurrent jobs to be run
if [ -n "${TRAVIS_JOB_ID}" ]; then
    cat >ci.bazelrc <<EOF
common --noshow_progress --noshow_loading_progress
build:ppc64le --jobs=1
run:ppc64le --jobs=1
EOF
fi

# Create the persistent docker volume
if [ -z "$(docker volume list | grep ${BUILDER})" ]; then
    docker volume create --name ${BUILDER}
fi

# Make sure that the output directory exists
docker run -v "${BUILDER}:/root:rw,z" --security-opt label:disable --rm ${KUBEVIRT_BUILDER_IMAGE} mkdir -p /root/go/src/kubevirt.io/kubevirt/_out

# Start an rsyncd instance and make sure it gets stopped after the script exits
RSYNC_CID=$(docker run -d -v "${BUILDER}:/root:rw,z" --security-opt label:disable --expose 873 -P ${KUBEVIRT_BUILDER_IMAGE} /usr/bin/rsync --no-detach --daemon --verbose)

function finish() {
    docker stop ${RSYNC_CID} >/dev/null 2>&1 &
    docker rm -f ${RSYNC_CID} >/dev/null 2>&1 &
}
trap finish EXIT

RSYNCD_PORT=$(docker port $RSYNC_CID 873 | cut -d':' -f2)

rsynch_fail_count=0

while ! rsync ${KUBEVIRT_DIR}/${RSYNCTEMP} "rsync://root@127.0.0.1:${RSYNCD_PORT}/build/${RSYNCTEMP}" &>/dev/null; do
    if [[ "$rsynch_fail_count" -eq 0 ]]; then
        printf "Waiting for rsyncd to be ready"
        sleep .1
    elif [[ "$rsynch_fail_count" -lt 30 ]]; then
        printf "."
        sleep 1
    else
        printf "failed"
        break
    fi
    rsynch_fail_count=$((rsynch_fail_count + 1))
done

printf "\n"

rsynch_fail_count=0

_rsync() {
    rsync -al "$@"
}

# Copy kubevirt into the persistent docker volume
_rsync \
    --delete \
    --exclude 'bazel-bin' \
    --exclude 'bazel-genfiles' \
    --exclude 'bazel-kubevirt' \
    --exclude 'bazel-out' \
    --exclude 'bazel-testlogs' \
    --exclude 'cluster-up/cluster/**/.kubectl' \
    --exclude 'cluster-up/cluster/**/.oc' \
    --exclude 'cluster-up/cluster/**/.kubeconfig' \
    --exclude "_out" \
    --exclude ".vagrant" \
    ${KUBEVIRT_DIR}/ \
    "rsync://root@127.0.0.1:${RSYNCD_PORT}/build"

volumes="-v ${BUILDER}:/root:rw,z"

# append .docker directory as volume
mkdir -p "${HOME}/.docker"
volumes="$volumes -v ${HOME}/.docker:/root/.docker:ro,z"

# Ensure that a bazel server which is running is the correct one
if [ -n "$(docker ps --format '{{.Names}}' | grep ${BUILDER}-bazel-server)" ]; then
    # check if the image is correct
    builder_id=$(docker inspect ${KUBEVIRT_BUILDER_IMAGE} | docker run --rm -i imega/jq:1.6 ".[0].Id")
    bazel_server_id=$(docker inspect ${BUILDER}-bazel-server | docker run --rm -i imega/jq:1.6 ".[0].Image")
    if [ "${builder_id}" != "${bazel_server_id}" ]; then
        echo "Bazel server is outdated, restarting ..."
        docker stop ${BUILDER}-bazel-server
    fi
fi

# Ensure that a bazel server is running
if [ -z "$(docker ps --format '{{.Names}}' | grep ${BUILDER}-bazel-server)" ]; then
    docker run --network host -d ${volumes} --security-opt label:disable --name ${BUILDER}-bazel-server -w "/root/go/src/kubevirt.io/kubevirt" --rm ${KUBEVIRT_BUILDER_IMAGE} hack/bazel-server.sh
fi

# Run the command
test -t 1 && USE_TTY="-it"
docker exec ${USE_TTY} ${BUILDER}-bazel-server /entrypoint.sh "$@"

# Copy the whole kubevirt data out to get generated sources and formatting changes
_rsync \
    --exclude 'bazel-bin' \
    --exclude 'bazel-genfiles' \
    --exclude 'bazel-kubevirt' \
    --exclude 'bazel-out' \
    --exclude 'bazel-testlogs' \
    --exclude 'cluster-up/cluster/**/.kubectl' \
    --exclude 'cluster-up/cluster/**/.oc' \
    --exclude 'cluster-up/cluster/**/.kubeconfig' \
    --exclude "_out" \
    --exclude "vendor" \
    --exclude ".vagrant" \
    --exclude ".git" \
    "rsync://root@127.0.0.1:${RSYNCD_PORT}/build" \
    ${KUBEVIRT_DIR}/

_rsync --delete "rsync://root@127.0.0.1:${RSYNCD_PORT}/build/manifests/generated/" "${KUBEVIRT_DIR}/manifests/generated"
_rsync --delete "rsync://root@127.0.0.1:${RSYNCD_PORT}/build/examples/" "${KUBEVIRT_DIR}/examples"
if [ "$SYNC_VENDOR" = "true" ]; then
    _rsync --delete "rsync://root@127.0.0.1:${RSYNCD_PORT}/vendor" "${VENDOR_DIR}/"
fi
# Copy the build output out of the container, make sure that _out exactly matches the build result
if [ "$SYNC_OUT" = "true" ]; then
    _rsync --delete "rsync://root@127.0.0.1:${RSYNCD_PORT}/out" ${OUT_DIR}
fi
