#!/usr/bin/bash
VSTORAGE_NFS_LIB=/usr/libexec/vstorage-nfs/nfs_functions
ROOT=""
SHARE_NAME=""

ARGS="${@}"
HIDE_HEADER=""

print_usage() {
        exec 1>&2
        echo "List existing NFS shares."
        echo "Usage:"
        echo " vstorage-nfs list [-n,--name NAME] [-A,--all] [-H,--no-header] [-X,--xml]"
        echo "Options:"
        echo "  -n,--name NAME          show information only for specified NFS share (optional)."
        echo "  -A,--all                show all shares on NFS_ROOT (optional)."
        echo "  -H, --no-header         suppress displaying the header row. Usable for scripts (optional)."
        echo "  -X, --xml               get output in XML (optional)."
        echo " "
        exit 1
}

parse_args() {
        while [ "${#}" -gt 0 ]; do
                case "${1}" in
                        "-r"|"--root")
                                [ -z "${2}" ] && print_usage
                                ROOT="${2}"
                                shift
                                shift
                                ;;
                        "-n"|"--name")
                                [ -z "${2}" ] && print_usage
                                SHARE_NAME="${2}"
                                shift
                                shift
                                ;;
                        "-A"|"--all")
                                SHOW_ALL="yes"
                                shift
                                ;;
                        "-H"|"--no-header")
                                HIDE_HEADER="1"
                                shift
                                ;;
                        "-X"|"--xml")
                                XML_MODE="1"
                                SHOW_ALL="1"
                                shift
                                ;;
                        "-h"|"--help")
                                print_usage
                                ;;
                        *)
                                echo "Unknown option '${1}'." 1>&2
                                print_usage
                                ;;
                esac
        done
}

get_remote_status() {
        local owner="$1"
        if [ -n "$owner" -a "$owner" != "$TARGET_NO_OWNER" ] ; then
                echo "remote"
        else
                echo "unregistered"
        fi
}

get_format() {
        echo -e "$1" | awk -F '!' \
        'BEGIN { numf=6 } { for (i=1; i<=numf; i++) { if(length($i) >= m[i]) m[i]=length($i)} } END { p=""; s=""; for(i=1;i<=numf; i++) { p=p",$"i; s=s"%-"m[i]"s " } ; print "{printf \""s"\\n\""p"}" }'
}

get_addrs() {
	local share=$1
	local out=""
	if [ -f "$NFS_ROOT/shares/$share/control/address" ]; then
		for a in `cat "$NFS_ROOT/shares/$share/control/address" 2>/dev/null`; do
			[ -n "$out" ] && out="$out,"
			out="$out`echo $a | cut -d '/' -f1`"
		done
	else
		out="unknown"
	fi
	echo $out
}

get_volumeid() {
	local share=$1
	local out=""
	if [ -f "$NFS_ROOT/shares/$share/control/volumeid" ]; then
		value=`cat "$NFS_ROOT/shares/$share/control/volumeid" 2>/dev/null`
		out="`echo $value`"
	else
		out="unknown"
	fi
	echo $out
}

get_keytab_status() {
	local share=$1
	local out="no"
	[ -f "$NFS_ROOT/shares/$share/control/krb5.keytab" ] && out="yes"

	echo $out
}

get_prometheus_addr() {
        local is_local="$1"

        if [ "x$is_local" = "xyes" ] ; then
                echo "$(cat $PCS_OSTOR_VAR_RUN/ostorfs.stat 2>/dev/null)"
        else
                echo ""
        fi
}

print_share() {
	local share="$1"
	local is_local="$2"
	local status=""
	local host=`cat "$NFS_ROOT/shares/$share/control/host" 2>/dev/null`
	if [ "x$is_local" = "xyes" ] ; then
		status=`pcs_nfs_get_status $share`
	else
		status=`get_remote_status $host`
		[ "$status" = "unregistered" ] && host="None"
	fi
	addr=`get_addrs $share`
	volumeid=`get_volumeid $share`
	keytab=`get_keytab_status $share`
	echo "$share!$status!$keytab!$host!$volumeid!$addr"
}

print_share_xml() {
        local share="$1"
        local is_local="$2"
        local status=""
        local prometheus_addr=""
        local host=`cat "$NFS_ROOT/shares/$share/control/host" 2>/dev/null`
        if [ "x$is_local" = "xyes" ] ; then
                status=`pcs_nfs_get_status $share`
        else
                status=`get_remote_status $host`
                [ "$status" = "unregistered" ] && host="None"
        fi
        addr=`get_addrs $share`
        volumeid=`get_volumeid $share`
        keytab=`get_keytab_status $share`
        prometheus_addr=`get_prometheus_addr $is_local`

        echo "<share>"
        echo "<name>$share</name>"
        echo "<host>$host</host>"
        echo "<status>$status</status>"
        echo "<addr>$addr</addr>"
        echo "<volumeid>$volumeid</volumeid>"
        echo "<keytab>$keytab</keytab>"
        echo "<prometheus>$prometheus_addr</prometheus>"
        print_exports_xml $share
        echo "</share>"
}

get_shares() {
	ls "$NFS_ROOT/shares" 2>/dev/nulll | while read share; do
		[ ! -d "$NFS_ROOT/shares/$share/control" ] && continue
		pcs_ha_is_registered_local $share $HOST_ID
                if [ $? -eq 0 ] ; then
                        is_local="yes"
                else
                        [ -z "$SHOW_ALL" ] && continue
                        is_local=""
                fi
                if [ -z "$XML_MODE" ] ; then
                        print_share $share $is_local
                else
			print_share_xml $share $is_local
                fi
	done
}

print_export() {
	local share=$1
	local export=$2
	local export_id=`cat $export/export_id`

	echo  "`basename $export`!$export_id" | awk -F  '!' '{ printf " Export: %s, Export_Id: %s \n", $1,$2}'
}

print_export_xml() {
        local share=$1
        local export=$2
        local name=`basename $export`
        local export_id=`cat $export/export_id`

        echo "<export>"
        echo "<name>$name</name>"
        echo "<id>$export_id</id>"
        echo "</export>"
}

print_exports() {
        local share=$1

        ls -d $NFS_ROOT/shares/$share/exports/* 2>/dev/null | while read export; do
                print_export $share $export
        done
}

print_exports_xml() {
        local share=$1

        echo "<exports>"

        ls -d $NFS_ROOT/shares/$share/exports/* 2>/dev/null | while read export; do
                print_export_xml $share $export
        done

        echo "</exports>"
}

show_share() {
	local share=$1
	local is_local="no"
	pcs_nfs_check_share $share
	local host=`cat "$NFS_ROOT/shares/$share/control/host" 2>/dev/null`
	pcs_ha_is_registered_local $share $HOST_ID
	if [ $? -eq 0 ] ; then
		is_local="yes"
		status=`pcs_nfs_get_status $share`
	else
		status=`get_remote_status $host`
		[ "$status" = "unregistered" ] && host="None"
	fi
        local host=`cat "$NFS_ROOT/shares/$share/control/host"`
        if [ "x$is_local" = "xyes" ] ; then
                status=`pcs_nfs_get_status $share`
        else
                status=`get_remote_status $host`
                [ "$status" = "unregistered" ] && host="None"
        fi

        if [ -n "$XML_MODE" ]; then
		echo "<?xml version=\"1.0\"?>"
		echo "<shares>"
		print_share_xml $share $is_local
		echo "</shares>"
		exit 0
	fi

	echo "Share $share:"
	echo " VolumeID:    `get_volumeid $share`"
	echo " Address(es): `get_addrs $share`"
	echo " Status:      $status"
	echo " Registered:  $is_local"
	echo " Host:        $host"
	echo " Keytab:      `get_keytab_status $share`"
        echo " Prometheus:  `get_prometheus_addr $is_local`"
        print_exports $share
}

list_shares() {
        if [ -n "$XML_MODE" ]; then
		echo "<?xml version=\"1.0\"?>"
		echo "<shares>"
		get_shares
		echo "</shares>"
		exit 0
	fi

	local shares=""
	[ -z "$HIDE_HEADER" ] && shares="NAME!STATUS!KEYTAB!HOST!VOLUMEID!ADDRESS(s)\n"
	shares="$shares$(get_shares)"
	fmt=`get_format "$hdr$shares"`
	for s in $shares; do
		echo -e $s | awk -F '!' "$fmt"
	done
}

if [ ! -x $VSTORAGE_NFS_LIB ] ; then
        echo "Unable find executable $VSTORAGE_NFS_LIB" 1>&2
        exit 1
fi

source $VSTORAGE_NFS_LIB
[ -f $NFS_ETC/config ] && source $NFS_ETC/config

parse_args $ARGS

NFS_ROOT=`pcs_nfs_get_root "${ROOT}"`
pcs_nfs_check_root

HOST_ID=`get_host_id`
[ $? -ne 0 ] && exit 2

if [ -n "$SHARE_NAME" ] ; then
	pcs_ha_lock_exec show_share "$SHARE_NAME"
else
	list_shares
fi
exit 0
