#!/bin/sh
#
#    byobu-status: byobu's cached status gathering
#
#    Copyright (C) 2011-2014 Dustin Kirkland
#
#    Authors: Dustin Kirkland <kirkland@byobu.org>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, version 3 of the License.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

PKG="byobu"
[ -r "$HOME/.byoburc" ] && . "$HOME/.byoburc"
[ -z "${BYOBU_PREFIX}" ] && export BYOBU_PREFIX="@prefix@" || export BYOBU_PREFIX
. "${BYOBU_PREFIX}/lib/${PKG}/include/common"

# Make sure status is not disabled
[ -f "$BYOBU_CONFIG_DIR/status.disable" ] && exit 0

# Clean and create cache directories
[ -d "$BYOBU_RUN_DIR/status.$BYOBU_BACKEND" ] || mkdir -p "$BYOBU_RUN_DIR/status.$BYOBU_BACKEND"
[ -d "$BYOBU_RUN_DIR/.last.$BYOBU_BACKEND" ] || mkdir -p "$BYOBU_RUN_DIR/.last.$BYOBU_BACKEND"

# Source configurations
. "${BYOBU_PREFIX}/lib/${PKG}/include/icons"
for i in "${BYOBU_PREFIX}/share/$PKG/status/status" "${BYOBU_PREFIX}/share/$PKG/status/statusrc" "$BYOBU_CONFIG_DIR/status" "$BYOBU_CONFIG_DIR/statusrc" "$BYOBU_CONFIG_DIR/color" "$BYOBU_CONFIG_DIR/color.tmux"; do
	[ -r "$i" ] && . "$i"
done
[ -r "$BYOBU_CONFIG_DIR/datetime.tmux" ] && . "$BYOBU_CONFIG_DIR/datetime.tmux"

case "$BYOBU_BACKEND" in
	screen)
		# Reload profile, if necessary
		if [ -e "/var/run/screen/S-$USER/$PKG.reload-required" ] || [ -e "$BYOBU_RUN_DIR/reload-required" ]; then
			if [ -r "$BYOBU_CONFIG_DIR/profile" ]; then
				# If the forced janitorial steps succeed, try a profile reload
				byobu-janitor --force && screen -X at 0 source "$BYOBU_CONFIG_DIR/profile" >/dev/null 2>&1
			fi
		fi
	;;
	tmux)
		# Fix status printing for small terminal sizes in tmux
		width=$(tmux list-windows -F "#{session_width}")
		if [ -r "$BYOBU_RUN_DIR/width" ]; then
			read w_last < $BYOBU_RUN_DIR/width 2>/dev/null 1>&2
		else
			w_last=0
		fi
		for w in $width; do
			if [ "$w" != "$w_last" ]; then
				# go through cat due to possible tmux/epoll bug
				tmux set -g status-left-length $(($w*1/4)) | cat >/dev/null 2>&1
				tmux set -g status-right-length $(($w*3/4)) | cat >/dev/null 2>&1
				printf "$w" > $BYOBU_RUN_DIR/width
				break
			fi
		done
	;;
esac

# Get the current timestamp
get_now; NOW=${_RET}

get_status() {
	local cachepath="$BYOBU_RUN_DIR/status.$BYOBU_BACKEND/$1"
	local lastpath="$BYOBU_RUN_DIR/.last.$BYOBU_BACKEND/$1"
	local lastrun=0
	[ -r "$lastpath" ] && read lastrun < "$lastpath"
	case "$1" in
		ip_address4)
			local IPV6=0
			local function="ip_address"
		;;
		ip_address6)
			local IPV6=1
			local function="ip_address"
		;;
		*)
			local function="$1"
		;;
	esac
	status_freq "$function"
	local expiry=$(($lastrun+$_RET))
	find_script "$function" && . "${_RET}"
	# Update cache now, if necessary
	if [ $NOW -ge $expiry ] || [ "$lastrun" = "0" ]; then
		"__$function" > "$cachepath".new
	fi
	# Check if we have data in the cache
	if [ -s "$cachepath".new ]; then
		# Looks like we have an updated cache, use it
		mv -f "$cachepath".new "$cachepath"
		printf "%s" "$NOW" > "$lastpath"
		IFS= read line < "$cachepath"; printf "%s" "$line"
	elif [ -s "$cachepath" ]; then
		# New cache is empty, but we have data from our last run, use it
		IFS= read line < "$cachepath"; printf "%s" "$line"
	fi
}

case "$1" in
	*left|*right)
		eval items="\$$1"
		for i in $items; do
			if [ "$BYOBU_BACKEND" = "tmux" ]; then
				case "$i" in
					\#date)
						if [ -n "$BYOBU_DATE" ]; then
							$BYOBU_SED_INLINE -e "/BYOBU_DATE=/d" "$BYOBU_CONFIG_DIR/datetime.tmux"
							printf "%s\n" 'BYOBU_DATE=' >> "$BYOBU_CONFIG_DIR/datetime.tmux"
							touch "$BYOBU_RUN_DIR/reload-required"
							continue
						fi
					;;
					\#time)
						if [ -n "$BYOBU_TIME" ]; then
							$BYOBU_SED_INLINE -e "/BYOBU_TIME=/d" "$BYOBU_CONFIG_DIR/datetime.tmux"
							printf "%s\n" 'BYOBU_TIME=' >> "$BYOBU_CONFIG_DIR/datetime.tmux"
							touch "$BYOBU_RUN_DIR/reload-required"
							continue
						fi
					;;
					date)
						if [ -z "$BYOBU_DATE" ]; then
							$BYOBU_SED_INLINE -e "/BYOBU_DATE=/d" "$BYOBU_CONFIG_DIR/datetime.tmux"
							printf "%s\n" 'BYOBU_DATE="%Y-%m-%d "' >> "$BYOBU_CONFIG_DIR/datetime.tmux"
							touch "$BYOBU_RUN_DIR/reload-required"
							continue
						fi
					;;
					time)
						_byobu_time_fmt="%H:%M:%S"
						[ "${TIME_SECONDS:-1}" = "0" ] && _byobu_time_fmt="%H:%M"
						if [ "$BYOBU_TIME" != "$_byobu_time_fmt" ]; then
							$BYOBU_SED_INLINE -e "/BYOBU_TIME=/d" "$BYOBU_CONFIG_DIR/datetime.tmux"
							printf 'BYOBU_TIME="%s"\n' "$_byobu_time_fmt" >> "$BYOBU_CONFIG_DIR/datetime.tmux"
							touch "$BYOBU_RUN_DIR/reload-required"
						fi
						unset _byobu_time_fmt
						continue
					;;
				esac
			fi
			case "$i" in \#*) continue ;; esac
			get_status "$i"
		done
	;;
	--detail)
		VER=
		if eval $BYOBU_TEST dpkg-query >/dev/null; then
			VER=$(set -- $(dpkg-query --show $PKG); printf "%s\n" "$2")
		fi
		printf "$PKG-$VER Detailed Status Navigation\n"
		if eval $BYOBU_TEST vim >/dev/null && `vim --version | grep -q +folding`; then
			printf "  Expand all - zr\t\tCollapse all - zm\n  Expand one - zo\t\tCollapse one - zc\n\n"
		fi
		for i in "$BYOBU_PREFIX/lib/$PKG"/*; do
			[ -f "$i" ] || continue
			i=${i##*/}
			case "$i" in
				include|menu|notify_osd|time_binary) continue ;;
			esac
			find_script "$i" && . "${_RET}"
			short=$(eval "__${i}" | $BYOBU_SED -e 's/^\s*//' -e 's/\s*$//' -e 's/.{[^}]*}//g')
			detail=$(eval "__${i}_detail" 2>/dev/null | $BYOBU_SED -e '/^$/d' -e 's/^/\t/g')
			printf "%s\n\t(%s)\n" "$short" "$i"
			[ -n "$detail" ] && printf "%s\n" "$detail"
		done
	;;
	color)
		[ -z "$FOREGROUND" ] && FOREGROUND="w"
		[ -z "$BACKGROUND" ] && BACKGROUND="k"
		printf "$ESC{= $BACKGROUND$FOREGROUND}"
	;;
esac
