#!/bin/bash

mkdir -p $LOG_DIR

# ------------------------------------- warn ----------
function warn { 
    echo "$0:" "$@" >&2 
}

# ------------------------------------- die ----------
function die {
    rc=$1
    shift
    warn "$@"
    exit $rc
}

# ------------------------------------ debug ---------
function debug {
    (( DEBUG > 0 )) && echo $@ >&2
}

# ------------------------------------- log ----------
# $1  : log file name
function log {
    local LOG=$1
    [ -z "$LOG" ] && return
    [ ! -d $LOG_DIR ] && echo "No 'logs' directory present" && return
    shift
    echo -n "$(date +"%Y/%m/%d %H:%M:%S") " | tee /dev/tty >> $LOG_DIR/$LOG
    cat - | tee /dev/tty >> $LOG_DIR/$LOG
    return 0
}

# ---------------------------- wait-confirmation ------
function wait-confirmation {
    (( QUIET == 0 )) || return
    echo $@
    echo Press [ENTER] to proceed, [Ctrl-C] to abort operation...
    read
}

# ---------------------- iterate-directories ----------
# $1  => base directory
# $2' => optional "--fail-on-errors" parameter
# $2+ => function to execute (plus arguments if any)
#
function iterate-directories {
    local DIR=$1
    shift
    [ -z $# ] && die 11 "echo Must provide at least 2 parameters"
    if [ "$1" == '--fail-on-errors' ]; then 
        local AUTOFAIL=FAIL
        shift
    else
        local AUTOFAIL=CONTINUE
    fi

    pushd $DIR >/dev/null
    IMAGEDIRS=$(sort-image-dirs)
    # if "etc" is present, move it to leading spot
    [[ $IMAGEDIRS =~ [[:space:]]etc[[:space:]] ]] && IMAGEDIRS="etc ${IMAGEDIRS//[[:space:]]etc[[:space:]]/ }"
    # same for 'base-centos7'
    [[ $IMAGEDIRS =~ [[:space:]]base-centos7[[:space:]] ]] && IMAGEDIRS="base-centos7 ${IMAGEDIRS//[[:space:]]base-centos7[[:space:]]/ }"
    for imagedir in $IMAGEDIRS
    do
        [[ ! -z "$SELECTED_MODULE_DIR" && "$imagedir" != "$SELECTED_MODULE_DIR" ]] && continue
        echo "[$imagedir] -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"
        pushd $imagedir >/dev/null
        IMAGE=$(get-image-name-from-makefile Makefile)
        $@
        local ERR_CODE=$?
        if [ $ERR_CODE -ne 0 ]; then
            echo Execution failed, code=$ERR_CODE
            [ $AUTOFAIL == 'FAIL' ] && popd && return 10
        fi
        popd >/dev/null
    done
    popd >/dev/null
}

# ---------------------------------- fetch-git-images --------
function fetch-git-images {
    local img_src_dir=$BASE_DIR/images/service
    pushd $img_src_dir &>/dev/null
    if [ -n "$SELECTED_MODULE_DIR" -a "$SELECTED_MODULE_DIR" != "all" ]; then
        git-clone-repo $SELECTED_MODULE_DIR
    else
        [ -d $GIT_MIGRA_DIR ] || return 0
        MIGRA_IMGS=$(ls -1 $GIT_MIGRA_DIR)
        for imagedir in $MIGRA_IMGS
        do
            if [ ! -d $imagedir ]; then
                git-clone-repo $imagedir
            fi
        done
        
    fi
    popd &>/dev/null
}

# ---------------------------------- git-clone-repo ----------
# $1 => image directory name
#
function git-clone-repo {
    local imagedir=$1
    echo "========== Cloning $imagedir ==========="
    git clone "$GIT_VSAAS/$imagedir"
    pushd $imagedir &>/dev/null
    git checkout dev
    git pull
    popd &>/dev/null
}

# ---------------------------------- iterate-dir-list --------
function iterate-dir-list {
    if [ "$1" == '--fail-on-errors' ]; then 
        local AUTOFAIL=FAIL
        shift
    else
        local AUTOFAIL=CONTINUE
    fi
    local DIR=$1
    shift
    local FUNC=$1
    shift
    local IMAGEDIRS=$@
    
    pushd $DIR >/dev/null
    for imagedir in $IMAGEDIRS
    do
        [[ ! -d "$imagedir" ]] && continue
        echo "[$imagedir] -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"
        pushd $imagedir >/dev/null
        IMAGE=$(get-image-name-from-makefile Makefile)
        $FUNC
        local ERR_CODE=$?
        if [ $ERR_CODE -ne 0 ]; then
            echo Execution failed, code=$ERR_CODE
            [ $AUTOFAIL == 'FAIL' ] && popd && return 10
        fi
        popd >/dev/null
    done
    popd >/dev/null
}

# --------------------- get-image-name-from-makefile ---------
function get-image-name-from-makefile {
    local MAKEFILE=$1
    grep ^IMAGE_NAME Makefile 2>/dev/null | cut -f2 -d= | tr -d ' '
}

# ------------------------------------- build-image ----------
# this function works in sub-directories with Makefile/Dockerfile
function build-image {
    if [ ! -f Makefile ] ; then
        echo SKIPPING $imagedir as Makefile is not present...
        return
    fi
    IMAGE=$(get-image-name-from-makefile Makefile)
    echo Processing image: $IMAGE | log builds
    make build GOPROXY=$GOPROXY | log builds
    if [ ${PIPESTATUS[0]} -ne 0 ]; then
        echo build-image failed | log builds
        return 11
    fi
    return 0
}

# ------------------------------------- pull-image ----------
function pull-image {
    if [ ! -f Makefile ] ; then
        echo SKIPPING $imagedir as Makefile is not present...
        return
    fi
    local IMAGE=$(get-image-name-from-makefile Makefile)
    echo Processing image: $IMAGE
    docker pull $REGISTRY/$IMAGE
    docker tag $REGISTRY/$IMAGE $IMAGE
    sleep 2
}

# ------------------------------------- push-vae-image -------
function push-vae-image {
    docker login -u $VAE_REGISTRY_USERNAME -p $VAE_REGISTRY_PASSWORD $VAE_REGISTRY_HOST
    [ $? != 0 ] && die 15 "Login to VAE registry failed"
    docker tag $IMAGE$IVER $VAE_REGISTRY_HOST/overcast/$SHORTNAME$IVER
    docker push $VAE_REGISTRY_HOST/overcast/$SHORTNAME$IVER
    docker logout $VAE_REGISTRY_HOST
}

# --------------------------------------------- make-image-list ---------
# $1=READY2GO => compile list of images requested for the product, ABORT if anything is missing
# $1=MISSING  => compile a list of missing images (so they can be built)
# $1=ALL      => compile a list of ALL images (GOOD and MISSING, so they can be REBUILD)
function make-image-list {
    local include=$1
    local abort_on_error=$([ "$include" == READY2GO ] && echo 1 || echo 0)
    local errors=0
    local LIST=''
    local TMP_FILE=/tmp/docker-images.$$
    debug INCLUDE=$include >&2
    docker images > $TMP_FILE
    while read -r line; do
        debug LINE=$line
        # overcast/api-php:1.0
        local IMAGE=${line%%:*}
        local IMG_VER=${line##*:}
        [[ "$line" == \#* ]] && continue
        [[ "$IMAGE" == *DEPLOY_LEVEL* ]] && continue  # skip "base level" lines
        [[ "$IMAGE" == *AVATAR_VERSION* ]] && continue  # skip "avatar version" lines
        # check image really exists locally
        local FOUND=$(cat $TMP_FILE | grep "^$IMAGE" | grep -v builder | grep -F " $IMG_VER ")
        #debug TMP_FILE=$TMP_FILE IMAGE=$IMAGE IMG_VER=$IMG_VER FOUND=$FOUND
	#overcast/api-php  1.1   0e9859204827  53 minutes ago      431.9 MB
        [ "$1" == 'ALL' ] && LIST="$LIST $line"
        if [ -z "$FOUND" ]; then
            [ "$include" == 'MISSING' ] && LIST="$LIST $line"
            (( DEBUG != 0 )) && echo Missing: $line >&2
            errors=$((errors + 1))
        else
            [ "$include" == 'READY2GO' ] && LIST="$LIST $line"
            (( DEBUG != 0 )) && echo GOOD: $line >&2
        fi
    done < $IMGLIST_FILE
    rm $TMP_FILE
    (( abort_on_error != 0 && errors > 0 )) && warn 'ABORTING: some of required images were missing' && echo ABORT
    echo $LIST
}

# -------------------------------------------- get-deploy-level --------
function get-deploy-level {
    while read -r line; do
        [[ "$line" == \#* ]] && continue
        # BASE_DEPLOY_LEVEL:001
        # overcast/api-php:1.0
        [ "${line%%:*}" == "BASE_DEPLOY_LEVEL" ] && echo ${line##*:}
    done < $IMGLIST_FILE
}

# ---------------------------------------- get-conf-deploy-level -------
function get-conf-deploy-level {
    while read -r line; do
        [[ "$line" == \#* ]] && continue
        # CONF_DEPLOY_LEVEL:39045
        # overcast/api-php:1.0
        [ "${line%%:*}" == "CONF_DEPLOY_LEVEL" ] && echo ${line##*:}
    done < $IMGLIST_FILE
}
