#!/bin/bash
#  vim:sw=8:noet
# SPDX-License-Identifier:  GPL-2.0+
#
# Logging subsystem for alt-rootfs-installer.
#
#   To initialize the subsystem use log_init() function. The subsystem works in
# two major modes "log" and "con".
#   The first mode is "log", it outputs everything to the log file. It is
# still possible to output messages to stdout, but one should use function
# from this module to achieve that.
#   The second mode is "con", it outputs everything to the terminal. In this
# mode it is also possible to redirect the output to a file. The module checks
# whether the file descriptor 1 is a terminal or not. That check was done to
# disable colors and column indentations to not clobber the output in the
# file.

. shell-error 2>/dev/null
. shell-terminfo 2>/dev/null

DEFAULT_LOG_FILE="$TMP/alt-rootfs-installer.log"

[ -n "$LOG_MODE" ] || LOG_MODE="log"
[ "$LOG_MODE" = "log" -a -z "$LOG_FILE" ] &&
	LOG_FILE="$DEFAULT_LOG_FILE"
LOG_FD1=1
LOG_FD2=2

ERROR_COLOR="red"
WARN_COLOR="magenta"
STATE_COLOR="blue"
NOTE_COLOR="cyan"

# Arguments:
# $1 -- a message to output
# $2 -- a prefix of the message
# $3 (optional) -- color of the prefix
__print_message() {
	# To logfile
	[ "$LOG_MODE" == "log" ] && echo "a-r-i: $2 ${1-}" # PART OF THE API

	# To stdout
	1>&$LOG_FD1 echo -n "a-r-i: " # PART OF THE API
	if [ -t "$LOG_FD1" ]; then
		1>&$LOG_FD1 color_text "$2 " $3
	else
		1>&$LOG_FD1 echo -n "$2 "
	fi
	1>&$LOG_FD1 echo "${1-}"
}

print_error() {
	__print_message "$1" "error:" $ERROR_COLOR # PART OF THE API
}

print_warning() {
	__print_message "$1" "warning:" $WARN_COLOR # PART OF THE API
}

print_state() {
	__print_message "$1" "state:" $STATE_COLOR # PART OF THE API
}

print_note() {
	__print_message "$1" "note:" $NOTE_COLOR # PART OF THE API
}

# Print text without a new line character. It is possible to change color
# and/or a column number to output.
#
# Arguments:
# $1 -- text to output
# $2 (optional) -- color ('-' to skip it)
# $3 (optional) -- a column number
printx() {
	local col=
	local color=
	[ "$LOG_MODE" == "log" ] && echo -n "${1-}"
	if [ -t "$LOG_FD1" ]; then
		[ $# -gt 2 ] && col="$3"
		[ $# -gt 1 ] && color="$2"
		[ -n "$col" ] && 1>&$LOG_FD1 terminfo_col "$col"
		[ "$color" == "-" ] && color=
		1>&$LOG_FD1 color_text "${1-}" "$color"
	else
		1>&$LOG_FD1 echo -n "${1-}"
	fi
}

# Print text with a new line character. It is possible to change color
# and/or a column number to output.
#
# Arguments:
# $1 -- text to output
# $2 (optional) -- color ('-' to skip it)
# $3 (optional) -- a column number
printn() {
	local col=
	local color=
	[ "$LOG_MODE" == "log" ] && echo "${1-}"
	if [ -t "$LOG_FD1" ]; then
		[ $# -gt 2 ] && col="$3"
		[ $# -gt 1 ] && color="$2"
		[ -n "$col" ] && 1>&$LOG_FD1 terminfo_col "$col"
		[ "$color" == "-" ] && color=
		1>&$LOG_FD1 color_message "${1-}" "$color"
	else
		1>&$LOG_FD1 echo "${1-}"
	fi
}

# Print a message to user only in the interactive mode.
#
# $1 -- text to output
# $2 (optional) -- color ('-' to skip it)
# $3 (optional) -- a column number
print2user() {
	[ ${BATCH_MODE-} ] && return
	printn "$@"
}

# Print a key-value option in the interactive mode only.
#
# Arguments:
# $1 -- key
# $2 -- value
print_opt2user() {
	[ ${BATCH_MODE-} ] && return
	printx "$1: "; printn "$2" green 20
}

# Print an error message and exit.
#
# Arguments:
# $1 -- an error message
fatal_error() {
	print_error "$@"
	exit 1
}

# Execute command and redirect stderr to /dev/tty
# $@ -- command and arguments to execute
log_errtty() {
	2>/dev/tty $@
}

# Initialize logging subsystem.
log_init() {
	# Initialize shell-terminfo from libshell
	terminfo_init

	if [ "$LOG_MODE" != "con" ]; then
		# cleanup log file
		local DIR="${LOG_FILE%/*}"
		if [ ! -d "$DIR" ]; then
			fatal_error "No such logging directory: '$DIR'"
		fi
		> "$LOG_FILE"
		exec {LOG_FD1}>&1 {LOG_FD2}>&2 >"$LOG_FILE" 2>&1
	fi
}
