#!/bin/sh
#
# Trame - SliTaz unified system administration backend.
# Read doc/README.md and doc/CONVENTIONS.md before adding sub-commands.
#
# Copyright (C) SliTaz GNU/Linux - BSD License
# Author: See AUTHORS files
#

# Locate libs: installed path first, then dev tree.
if [ -r /usr/lib/slitaz/trame/common.sh ]; then
	TRAME_LIB=/usr/lib/slitaz/trame
else
	TRAME_LIB="$(cd "$(dirname "$0")/../lib" && pwd)"
fi
. "$TRAME_LIB/common.sh"

# Single source for the sub-command list (dispatch + introspection).
TRAME_SUBS="system hostname service time network wifi locale log user storage kernel boot power display audio firewall keyboard mirror"

# Schema file for a sub: installed path first, then dev tree.
schema_file() {
	local f="$SCHEMA_DIR/$1.json"
	[ -r "$f" ] || f="$(dirname "$0")/../share/trame/schemas/$1.json"
	[ -r "$f" ] && printf '%s' "$f"
}

# --list-commands: one name per line; --json adds the description
# pulled from each schema (first "description" field = command-level).
list_commands() {
	local sub f desc first=1
	if [ "$json" = "yes" ]; then
		printf '['
		for sub in $TRAME_SUBS; do
			desc=""
			f=$(schema_file "$sub") && desc=$(sed -n \
				's/^{"command":"[^"]*","description":"\([^"]*\)".*/\1/p' \
				"$f" | head -1)
			[ $first -eq 1 ] || printf ','
			first=0
			printf '{"name":"%s","description":"%s"}' \
				"$sub" "$(trame_json_escape "$desc")"
		done
		printf ']\n'
	else
		for sub in $TRAME_SUBS; do echo "$sub"; done
	fi
}

# --schemas: JSON array of every sub-command schema, dispatch order.
# This is the Wove function-calling contract, in one shot.
schemas() {
	local sub f first=1
	printf '['
	for sub in $TRAME_SUBS; do
		f=$(schema_file "$sub") || continue
		[ $first -eq 1 ] || printf ','
		first=0
		tr -d '\n' < "$f"
	done
	printf ']\n'
}

usage() {
	cat << EOT

$(boldify "$(gettext 'Usage:')") trame <command> [args] [--options]

$(gettext "SliTaz unified system administration backend v$VERSION")

$(boldify "$(gettext 'Commands:')")
  system      $(gettext "System information (read-only)")
  hostname    $(gettext "Get or set the system hostname")
  service     $(gettext "Manage SysV init services")
  time        $(gettext "Get/set clock, NTP sync, timezone")
  network     $(gettext "Show/configure network interfaces")
  wifi        $(gettext "Scan, connect, disconnect Wi-Fi networks")
  locale      $(gettext "Get/set the system locale (LANG)")
  log         $(gettext "Show/follow/clear the Trame log")
  user        $(gettext "List/add/remove users; passwd; groups")
  storage     $(gettext "List/mount/umount block devices")
  kernel      $(gettext "Modules (lsmod/modprobe) and sysctl params")
  boot        $(gettext "GRUB menu: entries, default, timeout")
  power       $(gettext "Suspend, hibernate, cpufreq governor")
  display     $(gettext "List outputs, set resolution, backlight")
  audio       $(gettext "ALSA volume, mute, list sound cards")
  firewall    $(gettext "iptables INPUT: list, allow, deny, flush")
  keyboard    $(gettext "Console keymap: get, set, list")
  mirror      $(gettext "spk packages mirror: list, set")

$(boldify "$(gettext 'Universal options:')")
  --json          $(gettext "Emit JSON on stdout")
  --dry-run       $(gettext "Simulate, do not mutate")
  --explain       $(gettext "List commands that would run, as JSON")
  --schema        $(gettext "Print the sub-command JSON schema")
  --yes           $(gettext "Skip confirmations")
  --quiet         $(gettext "No stdout on success, exit code only")
  -h, --help      $(gettext "This help")

$(boldify "$(gettext 'Introspection:')")
  --list-commands $(gettext "List sub-commands (--json: with descriptions)")
  --schemas       $(gettext "All sub-command JSON schemas as one array")

EOT
	exit 0
}

# Parse the sub-command, leave args after it.
TRAME_SUB="$1"
case "$TRAME_SUB" in
	''|-h|--help|help|usage) usage ;;
	--version) echo "trame $VERSION"; exit 0 ;;
	--list-commands) list_commands; exit 0 ;;
	--schemas) schemas; exit 0 ;;
esac
shift

case " $TRAME_SUBS " in
	*" $TRAME_SUB "*)
		. "$TRAME_LIB/trame-$TRAME_SUB.sh"
		trame_${TRAME_SUB}_main "$@"
		exit 0 ;;
	*)
		trame_die $TRAME_EUSER "unknown command: $TRAME_SUB" ;;
esac
