#!/bin/bash
# Copyright (C) 2026 MOXA Inc. All rights reserved.
# This software is distributed under the terms of the MOXA SOFTWARE NOTICE.
# See the file LICENSE for details.
#
# Name:
#       MOXA Audio Control Utility
#
# Authors:
#       2026    Wilson Huang <WilsonYS.Huang@moxa.com>
#

source "/usr/lib/mx-gpio-lib"
source "/usr/lib/mx-common-lib"

MODEL_NAME=""
OS_ID="$(awk -v opt="ID" -F= '$1==opt { print $2 ;}' /etc/os-release | tr -d '"')"

TARGET_ACTION=""
TARGET_SPEAKER_STATUS=""

SPEAKER_STATUS_STR=("external" "embedded")

function MPC3001::profile() {
        DIP_SW_IT87_GPIO=77
        SPEAKER_CTRL_IT87_GPIO=87
}

function MPC3001::init() {
        return 0
}

function MPC3001::get_speaker_status() {
        local gpc_name
        local dip_state
        local ctrl_state

        if ! is_module_loaded gpio_it87; then
                echo "gpio_it87 driver is not loaded"
                exit 1
        fi

        gpc_name=$(gpio_get_gpiochip_name gpio_it87)

        dip_state=$(gpio_get_value_libgpiod $(gpc_it8786_remap ${DIP_SW_IT87_GPIO}) ${gpc_name})

        if [[ "${dip_state}" -eq 0 ]]; then
                echo "Current speaker status is ${SPEAKER_STATUS_STR[0]} (DIP SW forced)."
                return
        fi

        ctrl_state=$(gpio_get_value_libgpiod $(gpc_it8786_remap ${SPEAKER_CTRL_IT87_GPIO}) ${gpc_name})

        echo "${SPEAKER_STATUS_STR[${ctrl_state}]}"
}

function MPC3001::set_speaker_status() {
        local status=$1
        local gpc_name
        local dip_state
        local val

        if ! is_module_loaded gpio_it87; then
                echo "gpio_it87 driver is not loaded"
                exit 1
        fi

        gpc_name=$(gpio_get_gpiochip_name gpio_it87)

        dip_state=$(gpio_get_value_libgpiod $(gpc_it8786_remap ${DIP_SW_IT87_GPIO}) ${gpc_name})

        if [[ "${dip_state}" -eq 0 ]]; then
                echo "Cannot set speaker status: DIP switch forces external speaker."
                exit 1
        fi

        case "${status}" in
        external) val=0 ;;
        embedded) val=1 ;;
        esac

        gpio_set_value_libgpiod $(gpc_it8786_remap ${SPEAKER_CTRL_IT87_GPIO}) ${val} ${gpc_name}
}

function load_model_name() {
        for name in $(get_model_name_from_dmi_type12); do
                if [[ "$(type -t "${name}::profile")" = 'function' ]]; then
                        MODEL_NAME="${name}"
                        break
                fi
        done

        if [[ -z "${MODEL_NAME}" ]]; then
                for name in $(get_model_name_from_dmi_type1); do
                        if [[ "$(type -t "${name}::profile")" = 'function' ]]; then
                                MODEL_NAME="${name}"
                                break
                        fi
                done
        fi

        if [[ -z "${MODEL_NAME}" ]]; then
                echo "Unsupported model"
                exit 38
        fi
}

function script_init() {
        load_model_name

        if [[ ! $(type -t "${MODEL_NAME}"::profile) == function ]]; then
                echo "${MODEL_NAME} profile function is not define"
                exit 1
        fi

        "${MODEL_NAME}"::profile

        if [[ ! $(type -t "${MODEL_NAME}"::init) == function ]]; then
                echo "${MODEL_NAME} init function is not define"
                exit 1
        fi

        "${MODEL_NAME}"::init
}

function script_usage() {
cat << EOF
Usage:
        mx-audio-ctl [option]

Options:
        -s, --speaker [status]
                Get or set speaker output.
                Without [status]: get current speaker status.
                external --> set to external speaker
                embedded --> set to embedded speaker

        -h, --help
                Show this help message.

Example:
        Get current speaker status
        # mx-audio-ctl -s
        # mx-audio-ctl --speaker

        Set to external speaker
        # mx-audio-ctl -s external

        Set to embedded speaker
        # mx-audio-ctl --speaker embedded
EOF
}

function script_params() {
        if [[ $# -eq 0 ]]; then
                script_usage
                exit 1
        fi

        while [[ $# -gt 0 ]]; do
                case "$1" in
                -s | --speaker)
                        if [[ "$2" == "external" || "$2" == "embedded" ]]; then
                                TARGET_ACTION="set_speaker"
                                TARGET_SPEAKER_STATUS="$2"
                                shift 2
                        else
                                TARGET_ACTION="get_speaker"
                                shift
                        fi
                        ;;
                -h | --help)
                        script_usage
                        exit 0
                        ;;
                *)
                        echo "Unknown option: $1" >&2
                        script_usage
                        exit 22
                        ;;
                esac
        done
}

function main() {
        script_params "$@"
        script_init

        case "${TARGET_ACTION}" in
        get_speaker)
                "${MODEL_NAME}"::get_speaker_status
                ;;
        set_speaker)
                "${MODEL_NAME}"::set_speaker_status "${TARGET_SPEAKER_STATUS}"
                ;;
        esac
}

main "$@"
