#!/usr/bin/env bash

#
# get_available_versions
#
# reports latest available version and build of each package,
# as an associative array named AVAILABLE
#
# This needs to be declared prior to calling the function with
# declare -A AVAILABLE
#

function get_available_versions {
    echo "Checking available workflow package versions..."
    mapfile -t -s 2 < <(conda search 'dag-wf*')

    # versions are reported in ascending order hence we can just iterate through 
    # them and add them to VERSIONS, which will leave us with the newest version only
    for i in "${MAPFILE[@]}"; do
        declare -a f
        readarray -t f< <(echo $i|awk '{print $1,"\n",$2,"\n",$3}'|sed 's/[ \n]//g')
        AVAILABLE[${f[0]}]="${f[1]}:${f[2]}"
    done
    return
}

#
# get_installed_versions
#
# Reports on installed package versions and build, as an
# associative array named INSTALLED
#
# This needs to be declared prior to calling the function with
# declare -A INSTALLED
#

function get_installed_versions {
    echo "Checking installed workflow package versions..."
    mapfile -t -s 1 < <(conda list|grep 'dag-wf')
    for i in "${MAPFILE[@]}"; do
        declare -a f
        readarray -t f< <(echo $i|awk '{print $1,"\n",$2,"\n",$3}'|sed 's/[ \n]//g')
        INSTALLED[${f[0]}]="${f[1]}:${f[2]}"
    done
    return
}

#
# get_workflow_envs
#
# Reports on which automatically created dag-wf- environments exit
# as an array named ENVLIST
#
# This needs to be declared prior ot calling the function with
# declare -a ENVLIST
#

function get_workflow_envs {
	echo
	echo "Finding existing workflow environments..."
	echo
	mapfile -t < <(conda info --envs |grep dag-wf-)
	for path in "${MAPFILE[@]}"; do
		name=$(basename ${path})
		ENVLIST+=( "${name}" )
	done
	return
}


#
# show_change_log
#
# reports entries in changelog for version updates since installed version of each package
#
# reported log realtes to value of $package variable
#

function show_change_log {
	new_version=$(awk -F: '{print $1}' <<< $new_version)
	cur_version=$(awk -F: '{print $1}' <<< $cur_version)
	tmpfile=$(mktemp)
	log="$package-CHANGELOG"
	wget -q -O ${tmpfile} "$LOG_URL/$log"
	echo
	printf "${GREEN}${BOLD}$package:${DEF} Changes since version ${cur_version}:\n"
	echo
	
	while IFS= read -r line; do 
		if [[ "${cur_version}:" == "${line}" ]]; then
			break
		else 
			echo $line
		fi
	done <${tmpfile}
	
	rm ${tmpfile}
	return
}


#
# upgrade_dag_wg
#
# Upgrades dag-wf environment to version specified in wf_version variable
#

function upgrade_dag_wf {
	
	cmd="conda install -y dag-wf=${wf_version}"
	printf "${GREEN}Upgrading dag-wf...${DEF}"
	echo
	eval $cmd
	echo

}

#
# upgrade_envs
#
# upgrades environments contained in ENVLIST array
#

function upgrade_envs {
	
	for env in "${ENVLIST[@]}"; do
		echo
		printf "${GREEN}Upgrading ${env} environment...${DEF}\n"
		echo
		conda activate ${env}
		declare -A INSTALLED
		get_installed_versions
		
		cmd="conda install -y "
		for package in "${!INSTALLED[@]}"; do
			cmd+=" $package=${AVAILABLE[$package]}"
		done
		cmd=$(echo $cmd|sed 's/:/=/g')
		echo
		printf "${GREEN}Running upgrade...${DEF}\n"
		eval $cmd
	done
}

set -e
set -o pipefail

BOLD='\033[1m'
RED='\033[0;91m'
GREEN='\033[0;92m'
DEF='\033[0m'

LOG_URL="https://dag.compbio.dundee.ac.uk/dag-wf/"

source $CONDA_PREFIX/bin/dag-wf-parse-yaml
source $CONDA_PREFIX/../../etc/profile.d/conda.sh

declare -A AVAILABLE
declare -A INSTALLED
declare -a NEW
declare -a UPDATED
declare -a ENVLIST

get_installed_versions
get_available_versions
get_workflow_envs

PACKAGES=($(for each in ${!AVAILABLE[@]}; do echo $each; done | sort))
OUTPUT=("PACKAGE,INSTALLED,AVAILABLE\n")
for package in ${PACKAGES[*]};do
	out=""
    if [[ -z "${INSTALLED[$package]}" ]]; then
        NEW+=( "${package}" )
		out=$(printf "${RED}${AVAILABLE[$package]}${DEF}")
    elif [[ "${AVAILABLE[$package]}" != "${INSTALLED[$package]}" ]]; then
        UPDATED+=( "${package}" )
		out=$(printf "${RED}${AVAILABLE[$package]}${DEF}")
	else
		out=$(printf "${GREEN}${AVAILABLE[$package]}${DEF}")
    fi
    OUTPUT+="$package,${INSTALLED[$package]},$out\n"
done

echo
echo -e ${OUTPUT[@]}|sed 's/,/,|,/g'|column -s ',' -t

if [ "${#NEW[@]}" -gt 0 ]; then
    echo "The following new packages are available:"
    for package in "${NEW[@]}"; do
        echo -e "\t* $package"
    done
    echo
fi

if [ "${#UPDATED[@]}" -gt 0 ]; then
    for package in "${UPDATED[@]}"; do
		new_version=${AVAILABLE[$package]}
		cur_version=${INSTALLED[$package]}
		show_change_log
    done
    echo

	wf_version=$(echo ${AVAILABLE['dag-wf']}|sed -r 's/:([0-9])+$/=\1/') <<< ${AVAILABLE['dag-wf']}
	printf "${RED}"
	read -r -p "Do you wish to upgrade to the lastest versions? [y/N] " response
	printf "${DEF}"
	echo
	case "$response" in
    [yY][eE][sS]|[yY]) 
        echo
        upgrade_dag_wf
		upgrade_envs
        ;;
    *)
        echo "Exited without making any changes.."
        ;;
	esac
else
	echo 
	echo "No updates available"
	echo
fi
