#!/bin/sh
# Converts a uci config file into an appropriate mosquitto.conf snippet
# expected to be used in an init file to generate a config file to run from
# Karl Palsson <karlp@remake.is> 2012.
# Considered to be released into the public domain

[ -f $IPKG_INSTROOT/lib/functions.sh ] && . $IPKG_INSTROOT/lib/functions.sh

TCONF=/tmp/mosquitto.generated.$$.conf
while getopts "f:" o; do
    case $o in
    f)
        TCONF=$OPTARG
        ;;
    esac
done

if [ -e $TCONF ]; then
    echo "Odd, same temporary generated config file already existed: $TCONF"
    exit 1
fi

echo "Generating mosquitto config file in $TCONF"
NOW=$(date)
echo "# mosquitto.conf file generated from UCI config." >>$TCONF
echo "# Config snippet generated by $0 on $NOW" >>$TCONF
echo "#" >> $TCONF

# Usage: append_if cfg uci_name output_name
# add a config line of the form "output_name <value>"
# if the "uci_name" was found.
# output_name defaults to uci_name if not specified.
append_if() {
    local cfg="$1"
    local uci_name="$2"
    local out_name="$3"
    if [ -z "$out_name" ]; then
        out_name=$uci_name
    fi
    config_get val $cfg $uci_name
    if [ -n "$val" ]; then
        echo "$out_name $val" >> $TCONF
    fi
}

# mosquitto uses true/false, uci uses 1/0
# note that this is not shell truthy, but equality with 1!
append_bool() {
    if [ $2 -eq 1 ]; then
        echo "$1 true" >> $TCONF
    else
        echo "$1 false" >> $TCONF
    fi
}

# as per append_if, but gets the value as a uci bool, not raw
append_optional_bool() {
    local cfg="$1"
    local uci_name="$2"
    local out_name="$3"
    config_get val $cfg $uci_name
    if [ -n "$val" ]; then
        config_get_bool real $cfg $uci_name
        append_bool $out_name $real
    fi
}

mosq_general() {
    config_get destinations "$1" log_dest
    for dest in $destinations; do
        echo "log_dest $dest" >> $TCONF
    done

    config_get_bool no_remote "$1" no_remote_access 0
    if [ "$no_remote" -eq 1 ]; then
        echo "bind_address 127.0.0.1" >> $TCONF
    fi

    config_get port "$1" port 1883
    echo "port $port" >> $TCONF
    append_if "$1" protocol
    append_if "$1" max_inflight_messages
    append_if "$1" max_queued_messages

}

add_listener() {
    echo "" >> $TCONF
    config_get port "$1" port
    if [ -z "$port" ]; then
        echo "Ignoring listener section without port"
        return
    fi
    config_get_bool no_remote "$1" no_remote_access 0
    if [ "$no_remote" -eq 1 ]; then
        echo "listener $port 127.0.0.1" >> $TCONF
    else
        echo "listener $port" >> $TCONF
    fi

    append_if "$1" protocol
}

add_topic() {
    echo "topic $1" >> $TCONF
}

add_bridge() {
    config_get conn "$1" connection
    config_get addr "$1" address
    if [ -z "$conn" -o -z "$addr" ]; then
        echo "Ignoring bridge section, misisng connection/address"
        return
    fi
    echo "" >> $TCONF
    echo "# Bridge connection from UCI section" >> $TCONF
    append_if "$1" connection
    append_if "$1" address

    config_list_foreach "$1" topic add_topic
    append_optional_bool "$1" cleansession cleansession
    append_optional_bool "$1" try_private try_private

    append_if "$1" clientid
    append_if "$1" identity bridge_identity
    append_if "$1" psk bridge_psk
    append_if "$1" tls_version bridge_tls_version
}


config_load "mosquitto"
config_foreach mosq_general "mosquitto"
config_foreach add_listener "listener"
config_foreach add_bridge "bridge"
