#!/bin/bash
# ------------------------------------- USAGE ----------
function USAGE {
cat<<ENDUSAGE
        conf-helper push [(-v|--version)=ver]
        conf-helper publish [qa|prod]

    push       - Push configuration changes from svn to git, always to 'dev' branch
    publish    - changes from 'dev' branch to 'qa' or 'prod' brunch
    push-style - Push branding style files from svn to git

ENDUSAGE
}

SCRIPTDIR=$(dirname $0)
DEBUG=0

. $SCRIPTDIR/_environment
. $SCRIPTDIR/_functions

# --------------------------------------- conf-url ------------------------
function conf-url {
    if [ -z "$GIT_CONFIG_USERNAME"  ] || [ -z "$GIT_CONFIG_PASSWORD" ]; then
        echo $GIT_CONFIG_REPO
    else
        local PROTO=${GIT_CONFIG_REPO%%://*}
        local REPO=${GIT_CONFIG_REPO##*://}
        echo $PROTO://$GIT_CONFIG_USERNAME:$GIT_CONFIG_PASSWORD@$REPO
    fi
}

# --------------------------------------- conf-clone -----------------------
function conf-clone {
    local LOCATION=$1
    local CLONE_URL=$(conf-url)

    git clone --depth 1 $CLONE_URL $LOCATION
}

function prepare-git {
    # Prepare git environment
    [ -z "$(which git 2>/dev/null)" ] && die 48 "Git executable not found"
    if [ -z "$(git config --global user.email)" ]; then
        echo "Must initialize git config before commit"
        echo "Please, enter your email"
        read email
        [ -z "$email" ] && die 49 "Email cannot be empty"
        echo "Now input your full name"
        read name
        [ -z "$name" ] && die 49 "Name cannot be empty"

        git config --global user.email "$email"
        git config --global user.name "$name"
        git config --global credential.helper cache
        # Use caching credentials in memory for a long period of time
        git config --global credential.helper 'cache --timeout=864000'
    fi
}

# ------------------------------------------------ conf-push ---------------
function conf-push {
    local STAGE_CONF=$STAGE_DIR/conf
    rm -rf $STAGE_CONF
    mkdir -p $STAGE_CONF

    prepare-git

    pushd $STAGE_CONF &>/dev/null
    git clone --depth 1 -b master $GIT_CONFIG_BASE_REPO config-base &>/dev/null
    [ $? != 0 ] && die 55 "Error cloning $GIT_CONFIG_BASE_REPO"

    PRODUCT_VER=latest
    [ "$VERSION" == "latest" ] && VERSION=
    if [ -n "$VERSION" ]; then
        PRODUCT_VER=$VERSION
        export IMGLIST_FILE=$REV_DIR/overcast.$VERSION
        if [ ! -f $IMGLIST_FILE ]; then
            die 20 "Missing product versioned images list file for requested version=$VERSION"
        fi
        CONF_LEVEL=$(get-conf-deploy-level)
        [ -z "$CONF_LEVEL" ] && die 52 "CONF_DEPLOY_LEVEL is not specified for version=$VERSION"

        svn co -r $CONF_LEVEL http://svn.dev.videonext.net/svn/va/$SVN_BRANCH/docker/etc &>/dev/null
        [ $? != 0 ] && die 51 "SVN checkout of docker/etc failed!"
        rm -rf etc/.svn
        mkdir -p $STAGE_CONF/etc/module.conf
        pushd $STAGE_CONF/etc/module.conf

        local LIST=$(make-image-list ALL)
        for IMG_REV in $LIST; do
            # overcast/media-streamer:1.0
            local IMG_NAME=${IMG_REV%%:*}
            IMG_NAME=${IMG_NAME##*/}
            local VER=${IMG_REV##*:}
            local REPO_REV=$(grep "$VER:" "$BASE_DIR/images/service/$IMG_NAME/rev.list" | cut -d: -f2)
            echo checkout $IMG_NAME: $REPO_REV
            svn co -r $REPO_REV http://svn.dev.videonext.net/svn/va/$SVN_BRANCH/docker/images/service/$IMG_NAME/etc $IMG_NAME &>/dev/null
            rm -rf $IMG_NAME/.svn &>/dev/null
            rmdir --ignore-fail-on-non-empty $IMG_NAME &>/dev/null
        done
        popd &>/dev/null
    else
        CONF_LEVEL=$(svn info $BASE_DIR/etc|grep Revision:|cut -c 11-)
        svn co http://svn.dev.videonext.net/svn/va/$SVN_BRANCH/docker/etc &>/dev/null
        rm -rf etc/.svn

        # Copy module configuration files
        for IMG_NAME in $(ls $IMG_SRC_DIR); do
            pushd $IMG_SRC_DIR/$IMG_NAME &>/dev/null
            mkdir -p $STAGE_CONF/etc/module.conf/$IMG_NAME
            if [ -d etc ]; then
                [ -n "$(ls etc)" ] && cp -r etc/* $STAGE_CONF/etc/module.conf/$IMG_NAME/
            fi
            popd &>/dev/null
        done
    fi

    echo Pushing configuration to config-base
    rsync -r --delete --exclude='.git*' --exclude='version' --exclude '*branding.cloud/style*' etc/ config-base
    pushd config-base &>/dev/null
    echo $PRODUCT_VER > version
    git add --all . &>/dev/null
    git commit -m "Merge svn:config ver=$PRODUCT_VER rev=$CONF_LEVEL" &>/dev/null
    git push origin master &>/dev/null
    [ $? != 0 ] && die 56 "Error pushing changes to $GIT_CONFIG_BASE_REPO"
    popd &>/dev/null
    popd &>/dev/null
}

function conf-publish {
    local BRANCH=$1
    [[ ! "$BRANCH" =~ ^(qa|prod)$ ]] && die 39 Branch must be one of [qa, prod]

    local STAGE_CONF=$STAGE_DIR/conf
    rm -rf $STAGE_CONF
    mkdir -p $STAGE_CONF

    prepare-git

    pushd $STAGE_CONF &>/dev/null
    git clone --depth 1 -b master $GIT_CONFIG_BASE_REPO config-base &>/dev/null
    [ $? != 0 ] && die 55 "Error cloning $GIT_CONFIG_BASE_REPO"

    pushd config-base &>/dev/null
    git push origin master:$BRANCH
    popd &>/dev/null
    popd &>/dev/null
}

function style-push {
    local STAGE_CONF=$STAGE_DIR/conf
    rm -rf $STAGE_CONF
    mkdir -p $STAGE_CONF

    pushd $STAGE_CONF &>/dev/null
    git clone -b master $GIT_CONFIG_BASE_REPO config-base &>/dev/null
    [ $? != 0 ] && die 55 "Error cloning $GIT_CONFIG_BASE_REPO"

    # Checkout sdi/html
    echo Clone gui-admin/src/html
    git clone $GIT_VSAAS/gui-admin.git -b dev --depth 1 &>/dev/null || die 55 "Error cloning gui-admin"

    # Copy "style" subdirectory from all sdi modules
    mkdir -p $STAGE_CONF/style
    local moddir=gui-admin/src/html
    for sdimod in $(ls $moddir); do
        if [ -d $moddir/$sdimod/style ]; then
            mkdir -p style/$sdimod
            cp -rf $moddir/$sdimod/style/* style/$sdimod/
        fi
    done

    # Sync with existing git branding styles
    rsync -r --delete style/ config-base/branding.cloud/style
    pushd config-base &>/dev/null
    if [ -z "$(git status -s)" ]; then
        echo "Nothing to push"
    else
        git status -s
        echo Following changes will be pushed to 'config-base' repo
        echo Press Enter to proceed or Ctrl-C to abort operation.
        read
        git add --all .
        git commit -m "Merged from gui-admin/src/html"
        git push origin master
    fi
    popd &>/dev/null
}

# --------------------------------------------------------------------------
# ---------------------------------= MAIN =---------------------------------
# --------------------------------------------------------------------------

IMG_SRC_DIR=$BASE_DIR/images/service
IMAGES=''
export QUIET=0
export COMMAND=$1

[ -z "$COMMAND" ] && USAGE && die 1 "Need at least one argument"

for ARG in "$@"; do
    case $ARG in
        --debug)
            export DEBUG=1
            ;;
        -q|--quiet)
            export QUIET=1
            ;;
        -m=*|--message=*)
            COMMIT_MESSAGE="${ARG#*=}"
            ;;
        -v=*|--version=*)
            VERSION="${ARG#*=}"
            ;;
    esac
done

(( DEBUG == 0 )) || cat <<EOF
========== Processing command ==========
  COMMAND  => $COMMAND
  VERSION  => $VERSION
  QUIET    => $QUIET
  CI_MSG   => $COMMIT_MESSAGE
========================================
EOF

case $COMMAND in
    push)
        conf-push
        ;;
    publish)
        conf-publish $2
        ;;
    clone)
        conf-clone $2
        ;;
    push-style)
        style-push
        ;;
    *)
        USAGE
        die 1 "COMMAND not recognized"
esac
