#!/usr/local/bin/cbsd
#v11.1.12
CBSDMODULE="xen"
MYARG=""
MYOPTARG="alljails shownode display node header order"
MYDESC="List jail and status"
ADDHELP="alljails=1 - get jaillist from remote node\n\
shownode=1 - show nodename for jails\n\
node= only for current node\n\
header=0 don't print header\n\
display= list by comma for column. Default: jname,vm_ram,vm_cpus,vm_os_type,ip4_addr,status,vnc_port\n\
order= asc (default) or desc\n"
EXTHELP="wf_xls.html"

. ${subr}
. ${strings}
. ${nodes}

readconf xls.conf
init $*

oalljails="${alljails}"		# store original settings, they have more weight vs auto
oshownode="${shownode}"		# store original settings, they have more weight vs auto

# autosettings for alljails and shownode
is_cluster_mode
cluster_mode=$?         # cluster_mode=0 when we have any node

if [ ${cluster_mode} -eq 0 ]; then
	alljails=1
	shownode=1
fi

# restore manual settings
[ -n "${oalljails}" ] && alljails="${oalljails}"
[ -n "${oshownode}" ] && alljails="${oshownode}"

if [ -z "${display}" ]; then
#	case "${racct}" in
#		1)
#			display="jname,jid,vm_ram,vm_curmem,vm_cpus,pcpu,vm_os_type,ip4_addr,status,vnc_port"
#			;;
#		*)
			display="jname,vm_ram,vm_cpus,vm_os_type,ip4_addr,status,vnc_port"
#			;;
#	esac
fi

[ "${shownode}" = "1" ] && display="nodename,${display}"
[ -z "${order}" ] && order="asc"

#remove commas for loop action on header
mydisplay=$( echo ${display} | /usr/bin/tr ',' '  ' )

# upper for header
myheader=$( echo ${mydisplay} | /usr/bin/tr '[:lower:]' '[:upper:]' )

JLS=""

conv_status()
{
	local _maintain_reason=

	case "${status}" in
		0)
			status="Off"
			;;
		1)
			status="On"
			;;
		2)
			status="Slave"
			;;
		3)
			_maintain_reason=$( cbsdsql local SELECT maintenance FROM jails WHERE jname=\"${jname}\" 2>/dev/null )
			if [ -n "${_maintain_reason}" -a "${_maintain_reason}" != "0" ]; then
				status="Maintenance:${_maintain_reason}"
			else
				status="Maintenance"
			fi
			;;
		*)
			status="Unknown"
			;;
	esac
}

show_header()
{
	local _header="${WHITE}${BOLD}${myheader}${NORMAL}"
	[ ${header} -eq 1 ] && ${ECHO} ${_header}
}

# $1 - pid
get_rctl()
{
	local _val

	get_rctl_values -m process -p ${1} -j ${jname}
}

# -j $jname
# -u 1 - always show status as "Unregister"
populate_output_data()
{
	local unregister="0"
	local _tmpport _tmpbind
	local _pid=0
	local _A _ALLJCOL

	printf "${NORMAL}" # for column sort

	while getopts "j:u:" opt; do
		case "$opt" in
			j) jname="${OPTARG}" ;;
			u) unregister="1" ;;
		esac
		shift $(($OPTIND - 1))
	done

	_pid="0"

	#_ALLJCOL=$( echo ${_JCOL}| /usr/bin/tr " " "," )
	_ALLJCOL="vm_cpus,vm_ram,vm_os_type,vm_os_profile,ip4_addr"

	# empty string on remote node if cbsd version is mistmatch ( diff. jail schema )
	_A=$( 2>/dev/null env sqldelimer="|" ${miscdir}/sqlcli ${jailsysdir}/${jname}/local.sqlite "SELECT ${_ALLJCOL} FROM settings ORDER BY (created) DESC LIMIT 1;" )

	[ -z "${_A}" ] && return 1

	sqllist "${_A}" vm_cpus vm_ram vm_os_type vm_os_profile ip4_addr
	#echo "$vm_cpus $vm_ram $vm_os_type $vm_os_profile $ip4_addr"
	#return 0

	#populate values for in output string
	for _i in ${mydisplay}; do
		_val=""
		eval _val=\$$_i
		case "${_i}" in
			vm_ram)
				# convert to MB
				_val=$(( _val / 1024 / 1024 ))
				;;
			vnc_port)
				if [ -f "${jailsysdir}/${jname}/vnc_port" ]; then
					_tmpport=$( /bin/cat ${jailsysdir}/${jname}/vnc_port )
					_tmpbind=$( cbsdsql ${jailsysdir}/${jname}/local.sqlite "SELECT xen_vnc_tcp_bind FROM settings ORDER BY (created) DESC LIMIT 1;" 2>/dev/null )
					_val="${_tmpbind}:${_tmpport}"
				else
					_val="0"
				fi
				;;
			ip4_addr)
				_val=$( cbsdsql local "SELECT ip4_addr FROM xen WHERE jname=\"${jname}\"" 2>/dev/null )
				[ "${_val}" = "(null)" ] && _val="DHCP"
				;;
		esac
		[ "$1" = "Unregister" -a "${_i}" = "status" ] && _val="Unregister"

		[ -z "${_val}" ] && _val="\-"

		printf "${_val} "
	done

	printf "${NORMAL}\n"
}


# $1 - which file from. Eg: local
show_jaildata_from_sql()
{
	local _i

	#   set sqlfile for ". rcconf" including
	if [ -n "${1}" ]; then
		sqlfile="$1"
	else
		sqlfile="local"
	fi

	cbsdsql ${sqlfile} SELECT jname FROM jails WHERE emulator=\"xen\" ORDER BY jname ASC | while read jname; do
		_status=""
		. ${jrcconf}
		conv_status
		populate_output_data -j ${jname}
	done
}


show_local()
{
	local _errcode _status

	show_header

	show_jaildata_from_sql local

	# Unregister area
	[ ! -d "${jailrcconfdir}" ] && return 0
	ip4_addr="-"
	host_hostname="-"
	path="-"
	jid="0"
	vm_ram="-"
	vm_cpus="-"
	vm_os_type="-"
	path="-"
	status="-"
	vnc_port="-"

	for J in $( /bin/ls ${jailrcconfdir} ); do
		[ "${J}" = "dir.id" ] && continue
		jname=""
		[ ! -r ${jailrcconfdir}/${J} ] && continue
		. ${jailrcconfdir}/${J}

		[ -z "${jname}" ] && continue
		populate_output_data -u 1 -j ${jname}
		${ECHO} ${_status}
	done
}


show_remote()
{
	show_header

	if [ -z "${node}" ]; then
		node=$( cbsd node mode=list header=0 allinfo=0 )
	fi

	for _n in $node; do
		nodename="${_n}"
		show_jaildata_from_sql ${_n}
	done
}

show_jails()
{
	if [ -n "${node}" ]; then
		show_remote
		exit 0
	fi

	if [ "${alljails}" = "1" ]; then
		show_local
		header=0
		show_remote
	else
		show_local
	fi
}

. ${workdir}/jrctl.subr

#### MAIN
[ -z "${header}" ] && header=1
sqldelimer=" "

show_jails | /usr/bin/column -t
