#!/bin/bash

# This script helps to build release artifacts.
# arg1: profile, e.g. emqx | emqx-edge | emqx-pkg | emqx-edge-pkg
# arg2: artifact, e.g. rel | relup | zip | pkg

set -euo pipefail

PROFILE="$1"
ARTIFACT="$2"

# ensure dir
cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")"

PKG_VSN="$(./pkg-vsn.sh)"
export PKG_VSN

if [ "$(uname -s)" = 'Darwin' ]; then
	SYSTEM=macos
elif [ "$(uname -s)" = 'Linux' ]; then
    if grep -q -i 'centos' /etc/*-release; then
        DIST='centos'
        VERSION_ID="$(rpm --eval '%{centos_ver}')"
    else
        DIST="$(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/"//g')"
        VERSION_ID="$(sed -n '/^VERSION_ID=/p' /etc/os-release | sed -r 's/VERSION_ID=(.*)/\1/g' | sed 's/"//g')"
    fi
    SYSTEM="$(echo "${DIST}${VERSION_ID}" | sed -r 's/([a-zA-Z]*)-.*/\1/g')"
fi

ARCH="$(uname -m)"
case "$ARCH" in
    x86_64)
        ARCH='amd64'
        ;;
    aarch64)
        ARCH='arm64'
        ;;
    arm*)
        ARCH=arm
        ;;
esac
export ARCH

##
## Support RPM and Debian based linux systems
##
if [ "$(uname -s)" = 'Linux' ]; then
    case "${DIST:-}" in
        ubuntu|debian|raspbian)
            PKGERDIR='deb'
            ;;
        *)
            PKGERDIR='rpm'
            ;;
    esac
fi

log() {
    local msg="$1"
    # rebar3 prints ===>, so we print ===<
    echo "===< $msg"
}

make_rel() {
    # shellcheck disable=SC1010
    ./rebar3 as "$PROFILE" do release,tar
}

## unzip previous version .zip files to _build/$PROFILE/rel/emqx/releases before making relup
make_relup() {
    local lib_dir="_build/$PROFILE/rel/emqx/lib"
    local releases_dir="_build/$PROFILE/rel/emqx/releases"
    mkdir -p "$lib_dir" "$releases_dir"
    local releases=()
    if [ -d "$releases_dir" ]; then
        while read -r zip; do
            local base_vsn
            base_vsn="$(echo "$zip" | grep -oE "[0-9]+\.[0-9]+(\.[0-9]+|(-(alpha|beta)\.[0-9]))(-[0-9a-e]{8})?")"
            if [ ! -d "$releases_dir/$base_vsn" ]; then
                local tmp_dir
                tmp_dir="$(mktemp -d -t emqx.XXXXXXX)"
                unzip -q "$zip" "emqx/releases/*" -d "$tmp_dir"
                unzip -q "$zip" "emqx/lib/*" -d "$tmp_dir"
                cp -r -n "$tmp_dir/emqx/releases"/* "$releases_dir"
                cp -r -n "$tmp_dir/emqx/lib"/* "$lib_dir"
                rm -rf "$tmp_dir"
            fi
            releases+=( "$base_vsn" )
        done < <(find _upgrade_base -maxdepth 1 -name "*$PROFILE-$SYSTEM*-$ARCH.zip" -type f)
    fi
    if [ ${#releases[@]} -eq 0 ]; then
        log "No upgrade base found, relup ignored"
        return 0
    fi
    RELX_BASE_VERSIONS="$(IFS=, ; echo "${releases[*]}")"
    export RELX_BASE_VERSIONS
    ./rebar3 as "$PROFILE" relup --relname emqx --relvsn "${PKG_VSN}"
}

## make_zip turns .tar.gz into a .zip with a slightly different name.
## It assumes the .tar.gz has been built -- relies on Makefile dependency
make_zip() {
    # build the tarball again to ensure relup is included
    make_rel

    tard="/tmp/emqx_untar_${PKG_VSN}"
    rm -rf "${tard}"
    mkdir -p "${tard}/emqx"
    local relpath="_build/${PROFILE}/rel/emqx"
    local pkgpath="_packages/${PROFILE}"
    mkdir -p "${pkgpath}"
    local tarball="${relpath}/emqx-${PKG_VSN}.tar.gz"
    if [ ! -f "$tarball" ]; then
        log "ERROR: $tarball is not found"
    fi
    local zipball
    zipball="${pkgpath}/${PROFILE}-${SYSTEM}-${PKG_VSN}-${ARCH}.zip"
    tar zxf "${tarball}" -C "${tard}/emqx"
    (cd "${tard}" && zip -qr - emqx) > "${zipball}"
}

make_docker() {
    ## Build Docker image
    echo "DOCKER BUILD: Build Docker image."
    echo "DOCKER BUILD: build version -> $PKG_VSN."
    echo "DOCKER BUILD: docker repo -> emqx/$PROFILE "

    docker build --no-cache \
       --build-arg PKG_VSN="$PKG_VSN"  \
       --build-arg BUILD_FROM="emqx/build-env:erl${OTP:-23.2.7.2-emqx-2}-alpine" \
       --build-arg EMQX_NAME="$PROFILE" \
       --tag "emqx/$PROFILE:$PKG_VSN" \
       -f deploy/docker/Dockerfile .
}

log "building artifact=$ARTIFACT for profile=$PROFILE"

case "$ARTIFACT" in
    rel)
        make_rel
        ;;
    relup)
        make_relup
        ;;
    zip)
        make_zip
        ;;
    pkg)
        if [ -z "${PKGERDIR:-}" ]; then
            log "Skipped making deb/rpm package for $SYSTEM"
            exit 0
        fi
        make -C "deploy/packages/${PKGERDIR}" clean
        EMQX_REL="$(pwd)" EMQX_BUILD="${PROFILE}" SYSTEM="${SYSTEM}" make -C "deploy/packages/${PKGERDIR}"
        ;;
    docker)
        make_docker
        ;;
    *)
        log "Unknown artifact $ARTIFACT"
        exit 1
        ;;
esac
