#!/bin/bash
#
# Copyright (C) 2024 MOXA Inc. All rights reserved.
# This software is distributed under the terms of the MOXA SOFTWARE NOTICE.
# See the file LICENSE for details.
#
# Authors:
#   2024    Henry LC Chen <HenryLC.Chen@moxa.com>
# Description:
#   A wrapper to control io like Moxa Computer Interface Manager (MCIM).

TOOLS_PATH="/usr/sbin"

usage() {
cat << EOF

 The Moxa Computer Interface Manager (MCIM) is a tool designed to simplify
 user control of peripherals. The design of MCIM aims to enhance
 operational efficiency, enabling users to conveniently handle tasks
 related to peripheral devices.
Usage:
  mx-interface-mgmt [command]

Available Commands:
  cellular     Manages the cellular modem
  dio          Manages digital inputs and outputs for external devices
  led          Manages LED indicators
  relay        Manages the relay mode
  serialport   Manages the serial port

Flags:
  -h, --help      help for mx-interface-mgmt

Use "mx-interface-mgmt [command] --help" for more information about a command.

EOF
}

### cellular wrapper

cellular_usage() {
cat << EOF

Usage:
  mx-interface-mgmt cellular <NAME> <COMMAND> [ARG]

Available Commands:
  Get the power state of a cellular
    $ mx-interface-mgmt cellular <cellular_name> get_power
  Set the power state of a cellular
    $ mx-interface-mgmt cellular <cellular_name> set_power <power_state>
  Get the SIM slot of a cellular
    $ mx-interface-mgmt cellular <cellular_name> get_sim_slot
  Set the SIM slot of a cellular
    $ mx-interface-mgmt cellular <cellular_name> set_sim_slot <sim_slot>

Arguments:
  cellular_name: The slot number of cellular (e.g. 1|2)
  power_state: on|off
  sim_slot: 1|2

EOF
}

cellular_get_power() {
	$TOOLS_PATH/mx-module-ctl -s "$1" -p
}

cellular_set_power() {
	$TOOLS_PATH/mx-module-ctl -s "$1" -p "$2"
}

cellular_get_sim_slot() {
	$TOOLS_PATH/mx-module-ctl -s "$1" -i
}

cellular_set_sim_slot() {
	$TOOLS_PATH/mx-module-ctl -s "$1" -i "$2"
}

cellular_wrapper() {
	if [[ ! -f  "$TOOLS_PATH/mx-module-ctl" ]]; then
		echo "Error: cellular control is not available"
		exit 1
	fi
	case $2 in
		-h | --help)
			cellular_usage
			exit 0
			;;
		*)
			case $3 in
			get_power)
				if [[ ! $# -eq 3 ]]; then
					echo "Error: invalid cellular command, please check help menu"
					exit 1
				fi
				cellular_get_power "$2"
				;;
			set_power)
				if [[ ! $# -eq 4 ]]; then
					echo "Error: invalid cellular command, please check help menu"
					exit 1
				fi
				cellular_set_power "$2" "$4"
				;;
			get_sim_slot)
				if [[ ! $# -eq 3 ]]; then
					echo "Error: invalid cellular command, please check help menu"
					exit 1
				fi
				cellular_get_sim_slot "$2"
				;;
			set_sim_slot)
				if [[ ! $# -eq 4 ]]; then
					echo "Error: invalid cellular command, please check help menu"
					exit 1
				fi
				cellular_set_sim_slot "$2" "$4"
				;;
			*)
				echo "Error: invalid cellular command, please check help menu"
				exit 1
				;;
		esac
	esac
}

### dio wrapper

dio_usage() {
cat << EOF

Usage:
  mx-interface-mgmt dio <NAME> <COMMAND> [ARG]

Available Commands:
  Get the state of a dio
    $ mx-interface-mgmt dio <dio_name> get_state
  Set the state of a dio
    $ mx-interface-mgmt dio <dio_name> set_state <dio_state>

Arguments:
  dio_name: The name of dio (e.g. DI0、DO0)
  dio_state: 0(low)|1(high)

EOF
}

dio_get_state() {
	dio_direction=$(echo "$1" | cut -c1-2)
	dio_num=$(echo "$1" | cut -c3-)

	case $dio_direction in
		DI)
			$TOOLS_PATH/mx-dio-ctl -i "$dio_num"
			;;
		DO)
			$TOOLS_PATH/mx-dio-ctl -o "$dio_num"
			;;
		*)
			echo "Error: Unknown direction"
			exit 1
			;;
	esac
	
}

dio_set_state() {
	dio_direction=$(echo "$1" | cut -c1-2)
	dio_num=$(echo "$1" | cut -c3-)

	case $dio_direction in
		DI)
			echo "Error: DI cannot set state"
			exit 1
			;;
		DO)
			$TOOLS_PATH/mx-dio-ctl -o "$dio_num" -s "$2"
			;;
		*)
			echo "Error: Unknown direction"
			exit 1
			;;
	esac
}

dio_wrapper() {
	if [[ ! -f  "$TOOLS_PATH/mx-dio-ctl" ]]; then
		echo "Error: dio control is not available"
		exit 1
	fi
	case $2 in
		-h | --help)
			dio_usage
			exit 0
			;;
		*)
			case $3 in
			get_state)
				if [[ ! $# -eq 3 ]]; then
					echo "Error: invalid dio command, please check help menu"
					exit 1
				fi
				dio_get_state "$2"
				;;
			set_state)
				if [[ ! $# -eq 4 ]]; then
					echo "Error: invalid dio command, please check help menu"
					exit 1
				fi
				dio_set_state "$2" "$4"
				;;
			*)
				echo "Error: invalid dio command, please check help menu"
				exit 1
				;;
		esac
	esac
}

### led wrapper

led_usage() {
cat << EOF

Usage:
  mx-interface-mgmt led <NAME> <COMMAND> [ARG]

Available Commands:
  Get the state of a LED
    $ mx-interface-mgmt led <led_name> get_state
  Set the state of a LED
    $ mx-interface-mgmt led <led_name> set_state <led_state>

Arguments:
  led_name: The number of LED (e.g. 0, 1, 2, ......)
  led_state: on|off

EOF
}

led_get_state() {
	$TOOLS_PATH/mx-led-ctl -i "$1"
}

led_set_state() {
	$TOOLS_PATH/mx-led-ctl -i "$1" "$2"
}

led_wrapper() {
	if [[ ! -f  "$TOOLS_PATH/mx-led-ctl" ]]; then
		echo "Error: led control is not available"
		exit 1
	fi
	case $2 in
		-h | --help)
			led_usage
			exit 0
			;;
		*)
			case $3 in
			get_state)
				if [[ ! $# -eq 3 ]]; then
					echo "Error: invalid led command, please check help menu"
					exit 1
				fi
				led_get_state "$2"
				;;
			set_state)
				if [[ ! $# -eq 4 ]]; then
					echo "Error: invalid led command, please check help menu"
					exit 1
				fi
				led_set_state "$2" "$4"
				;;
			*)
				echo "Error: invalid led command, please check help menu"
				exit 1
				;;
		esac
	esac
}

### relay wrapper

relay_usage() {
cat << EOF

Usage:
  mx-interface-mgmt relay <NAME> <COMMAND> [ARG]

Available Commands:
  Get the mode of a relay
    $ mx-interface-mgmt relay <relay_name> get_mode
  Set the mode of a relay
    $ mx-interface-mgmt relay <relay_name> set_mode <relay_mode>

Arguments:
  relay_name: The number of relay (e.g. 0, 1, 2, ......)
  relay_mode: 0|1
              0 --> set to NC (Normal Closed) mode
              1 --> set to NO (Normal Open) mode

EOF
}

relay_get_mode() {
	$TOOLS_PATH/mx-relay-ctl -p "$1"
}

relay_set_mode() {
	$TOOLS_PATH/mx-relay-ctl -p "$1" -m "$2"
}

relay_wrapper() {
	if [[ ! -f  "$TOOLS_PATH/mx-relay-ctl" ]]; then
		echo "Error: relay control is not available"
		exit 1
	fi
	case $2 in
		-h | --help)
			relay_usage
			exit 0
			;;
		*)
			case $3 in
			get_mode)
				if [[ ! $# -eq 3 ]]; then
					echo "Error: invalid relay command, please check help menu"
					exit 1
				fi
				relay_get_mode "$2"
				;;
			set_mode)
				if [[ ! $# -eq 4 ]]; then
					echo "Error: invalid relay command, please check help menu"
					exit 1
				fi
				relay_set_mode "$2" "$4"
				;;
			*)
				echo "Error: invalid relay command, please check help menu"
				exit 1
				;;
		esac
	esac
}



### serialport wrapper

serialport_usage() {
cat << EOF

Usage:
  mx-interface-mgmt serialport <NAME> <COMMAND> [ARG]

Available Commands:
  Get the interface of a serial port
    $ mx-interface-mgmt serialport <serialport_name> get_interface
  Set the interface of a serial port
    $ mx-interface-mgmt serialport <serialport_name> set_interface <serial_interface>

Arguments:
  serialport_name: The number of serial port (e.g. 0, 1, 2, ......)
  serial_interface:
				0 --> set to RS-232 mode
				1 --> set to RS-485-2W mode
				2 --> set to RS-422 mode
				3 --> set to RS-485-4W mode

EOF
}

serialport_get_interface() {
	$TOOLS_PATH/mx-uart-ctl -p "$1"
}

serialport_set_interface() {
	$TOOLS_PATH/mx-uart-ctl -p "$1" -m "$2"
}

serialport_wrapper() {
	if [[ ! -f  "$TOOLS_PATH/mx-uart-ctl" ]]; then
		echo "Error: serial port mode control is not available"
		exit 1
	fi
	case $2 in
		-h | --help)
			serialport_usage
			exit 0
			;;
		*)
			case $3 in
			get_interface)
				if [[ ! $# -eq 3 ]]; then
					echo "Error: invalid serialport command, please check help menu"
					exit 1
				fi
				serialport_get_interface "$2"
				;;
			set_interface)
				if [[ ! $# -eq 4 ]]; then
					echo "Error: invalid serialport command, please check help menu"
					exit 1
				fi
				serialport_set_interface "$2" "$4"
				;;
			*)
				echo "Error: invalid serialport command, please check help menu"
				exit 1
				;;
		esac
	esac
}

main() {
	### Parameter check
	if [[ $# -lt 1 ]]; then
		usage
		exit 0
	fi

	case $1 in
		cellular)
			cellular_wrapper "$@"
			;;
		dio)
			dio_wrapper "$@"
			;;
		led)
			led_wrapper "$@"
			;;
		relay)
			relay_wrapper "$@"
			;;
		serialport)
			serialport_wrapper "$@"
			;;
		-h | --help)
			usage
			exit 0
			;;
		*)
			echo "Error: unknown command: $1"
			exit 1
			;;
	esac
}

main $@
