#!/usr/bin/env bash

# Contains sources from https://github.com/debuerreotype/debuerreotype

set -Eeuo pipefail
thisDir="$(dirname "$(readlink -f "${BASH_SOURCE}")")"
versionfile="$(readlink -f "${thisDir}/../VERSION")"
startdate="Mar 31 00:00:00 UTC 2020"
build_os="$(uname -s)"

function check_command() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "Error: The binary '$1' could not be found. Please make sure to install it." >&2
    exit 1
  fi
}

# Use "gdate" & sed (GNU) which must be installed by "Homebrew"
# on macOS systems to have a normalized date interface
if [ "Darwin" == $build_os ]; then
        date_gnu="gdate"
        sed_gnu="gsed"
else
        date_gnu="date"
        sed_gnu="sed"
fi
check_command "$date_gnu"
check_command "$sed_gnu"

source "${thisDir}/.constants.sh" \
	--flags 'major,minor,date,datefull,epoch,git' \
	--usage '[ --major | --minor | --date | --datefull | --epoch | --git ] [<garden-version>|<timestamp>]' \
	--sample '20200427' \
	--sample '--date 27.1' \
	--help   "Generates version dependent values according to the file $versionfile or to the parameter handed over. Versions can be converted adequately

--major 	prints only the major version
--minor		prints only the minor version
--date 		prints the date according to the version e.g. 20200427 if garden-version=27
--datefull	prints a full date deteministically usable by debootstrap
--epoch		prints the seconds sinc 19700101 till garden-version
--git		prints the version plus the last git-hash

If no parameter is specified the full version <major>.<minor> e.g. 27.5 is printed. The version is taken from $versionfile. On HEAD this should always evaluate to 'today', on branch versions this always should resolve to the next version that will be build e.g. 27.1. This implies there is no branch with a .0 in the $versionfile file.
The version calculated expresses the days since $startdate. Calculation is always UTC based."

eval "${dgetopt}"
typeout="default"
while true; do
	flag="$1"; shift
	dgetopt-case "${flag}"
	case "${flag}" in
		--major|--minor|--date|--datefull|--epoch|--git)		
			typeout="${flag}"   ;;
		--)	break ;;
		*) 	eusage "unknown flag '${flag}'" ;;
	esac
done

# Checks repo.gardenlinux.io for the highest available suite minor for the given major
function get_minor_from_repo {
  minor=0   # running index
  limit=100 # hard limit the search in case of unexpected curl results
  major=$1  # major to check the latest minor for
  repo_url="https://repo.gardenlinux.io/gardenlinux/dists/$major.__MINOR__/Release"
  while [ $minor -le $limit ]
  do
    check_url=${repo_url//__MINOR__/$minor}
    if curl -s $check_url| grep -q "Error"; then
      ((minor--))
      echo $minor
      return
    fi
    ((minor++))
  done
}

input="${1:-$($sed_gnu -e "s/#.*\$//" -e "/^$/d" "${versionfile}")}";  shift || true
input=$($sed_gnu "s/^[[:space:]]*//;s/[[:space:]]*\$//" <<< ${input})

# no version / timestamp on versionfile
[ -z ${input} ] && input="today"

minor=0
if [[ ${input} =~ ^[0-9\.]*$ && $(cut -d. -f1 <<< ${input}) -lt 10000000 ]]; 
then	[ $(cut -d. -sf3 <<< ${input}) ] && eusage "invalid version format ${input}. should be <major>[.<minor>]"

	major="$(cut -d. -f1 <<< ${input})"
	if [ $(cut -d. -sf2 <<< ${input}) ]; then 
		minor="$(cut -d. -f2 <<< ${input})"
	else 
		minor=$(get_minor_from_repo $major)
	fi
	version="${major}.${minor}"
else 
  if	[[ ${input} = today ]] || [[ ${input} = experimental ]];
	then	indate=$($date_gnu --date "today" +%s 2>/dev/null)
		major="$(( (${indate} - $($date_gnu --date "${startdate}" +%s)) / (60*60*24) ))"
		version=${input}
	else	indate=$($date_gnu --date "${input}" +%s 2>/dev/null) || eusage "invalid date ${input}"
		major="$(( (${indate} - $($date_gnu --date "${startdate}" +%s)) / (60*60*24) ))"
		version="${major}.${minor}"
	fi
fi

case "${typeout}" in
	--major)	echo ${major} ;;
	--minor)	echo ${minor} ;;
	--date)		$date_gnu --date "${startdate} + ${major} days" +%Y%m%d ;;
	--datefull)	$date_gnu --date "${startdate} + ${major} days" +%Y%m%dT%H%M%SZ ;;
	--epoch)	$date_gnu --date "${startdate} + ${major} days" +%s ;;
	--git)		echo "${version}-$(git -C "${scriptsDir}" rev-parse --short 'HEAD^{commit}')" ;;
        *)		echo "${version}" ;;
esac
