#!/bin/sh
#
# SPDX-License-Identifier: GPL-3.0-or-later
# myMPD (c) 2018-2025 Juergen Mang <mail@jcgames.de>
# https://github.com/jcorporation/mympd

CONFIG_DIR="/var/lib/mympd/config"
MYMPD_BIN="$(command -v mympd)"

while getopts ':c:s:b:' OPTION
do
    case "$OPTION" in
        b) MYMPD_BIN="$OPTARG" ;;
        c) CONFIG_DIR="$OPTARG" ;;
        s) MYMPD_SYSTEMD="$OPTARG" ;;
        *)
            echo "Usage: $(basename "$0") [-b </usr/bin/mympd>] [-c </var/lib/mympd/config>] [-s <0|1>] [SETTING VALUE ...]"
            echo "Options"
            echo "  -b Path to myMPD binary"
            echo "  -c Path to myMPD config directory, default: /var/lib/mympd/config"
            echo "  -s 0 = myMPD runs with normal linux user account"
            echo "     1 = myMPD ist started with systemd private user"
            exit 1
            ;;
    esac
done
shift "$((OPTIND - 1))"

if [ -z "$MYMPD_BIN" ] || [ ! -x "$MYMPD_BIN" ]
then
    echo "mympd not found"
    exit 1
fi

if [ -z "$MYMPD_SYSTEMD" ]
then
    if grep "DynamicUser=yes" "/usr/lib/systemd/system/mympd.service" > /dev/null 2>&1
    then
        MYMPD_SYSTEMD=1
    else
        MYMPD_SYSTEMD=0
    fi
fi

# whiptail
WHIPTAIL=$(command -v whiptail)
if [ -z "$WHIPTAIL" ]
then
    echo "whiptail not found"
    exit 1
fi

BACKTITLE="myMPD configuration"
MENU_WIDTH="40"

export NEWT_COLORS='
root=,blue
checkbox=black,lightgray
actlistbox=white,blue
roottext=,blue
disabledentry=gray,
entry=white,gray'

set_default() {
    MYMPD_ACL=""
    MYMPD_ALBUM_GROUP_TAG="Date"
    MYMPD_ALBUM_MODE="adv"
    MYMPD_CACHE_COVER_KEEP_DAYS="31"
    MYMPD_CACHE_LYRICS_KEEP_DAYS="31"
    MYMPD_CACHE_MISC_KEEP_DAYS="1"
    MYMPD_CACHE_THUMBS_KEEP_DAYS="31"
    MYMPD_LOGLEVEL="5"
    MYMPD_URI="auto"
    MYMPD_SAVE_CACHES="true"
    MYMPD_SCRIPTACL="+127.0.0.1"
    MYMPD_STICKERS="true"
    MYMPD_STICKERS_PAD_INT="false"
    MYMPD_HTTP_HOST="[::]"
    MYMPD_HTTP="true"
    MYMPD_HTTP_PORT="80"
    MYMPD_SSL="true"
    MYMPD_SSL_PORT="443"
    MYMPD_SSL_SAN=""
    MYMPD_CUSTOM_CERT="false"
    MYMPD_SSL_CERT=""
    MYMPD_SSL_KEY=""
    MYMPD_WEBRADIODB="true"
}

read_config() {
    [ -f "${CONFIG_DIR}/acl" ] && read -r MYMPD_ACL < "${CONFIG_DIR}/acl"
    [ -f "${CONFIG_DIR}/album_group_tag" ] && read -r MYMPD_ALBUM_GROUP_TAG < "${CONFIG_DIR}/album_group_tag"
    [ -f "${CONFIG_DIR}/album_mode" ] && read -r MYMPD_ALBUM_MODE < "${CONFIG_DIR}/album_mode"
    [ -f "${CONFIG_DIR}/cache_cover_keep_days" ] && read -r MYMPD_CACHE_COVER_KEEP_DAYS < "${CONFIG_DIR}/cache_cover_keep_days"
    [ -f "${CONFIG_DIR}/cache_lyrics_keep_days" ] && read -r MYMPD_CACHE_LYRICS_KEEP_DAYS < "${CONFIG_DIR}/cache_lyrics_keep_days"
    [ -f "${CONFIG_DIR}/cache_misc_keep_days" ] && read -r MYMPD_CACHE_MISC_KEEP_DAYS < "${CONFIG_DIR}/cache_misc_keep_days"
    [ -f "${CONFIG_DIR}/cache_thumbs_keep_days" ] && read -r MYMPD_CACHE_THUMBS_KEEP_DAYS < "${CONFIG_DIR}/cache_thumbs_keep_days"
    [ -f "${CONFIG_DIR}/loglevel" ] && read -r MYMPD_LOGLEVEL < "${CONFIG_DIR}/loglevel"
    [ -f "${CONFIG_DIR}/mympd_uri" ] && read -r MYMPD_URI < "${CONFIG_DIR}/mympd_uri"
    [ -f "${CONFIG_DIR}/save_caches" ] && read -r MYMPD_SAVE_CACHES < "${CONFIG_DIR}/save_caches"
    [ -f "${CONFIG_DIR}/scriptacl" ] && read -r MYMPD_SCRIPTACL < "${CONFIG_DIR}/scriptacl"
    [ -f "${CONFIG_DIR}/stickers" ] && read -r MYMPD_STICKERS < "${CONFIG_DIR}/stickers"
    [ -f "${CONFIG_DIR}/stickers_pad_int" ] && read -r MYMPD_STICKERS_PAD_INT < "${CONFIG_DIR}/stickers_pad_int"
    [ -f "${CONFIG_DIR}/http_host" ] && read -r MYMPD_HTTP_HOST < "${CONFIG_DIR}/http_host"
    [ -f "${CONFIG_DIR}/http" ] && read -r MYMPD_HTTP < "${CONFIG_DIR}/http"
    [ -f "${CONFIG_DIR}/http_port" ] && read -r MYMPD_HTTP_PORT < "${CONFIG_DIR}/http_port"
    [ -f "${CONFIG_DIR}/ssl" ] && read -r MYMPD_SSL < "${CONFIG_DIR}/ssl"
    [ -f "${CONFIG_DIR}/ssl_port" ] && read -r MYMPD_SSL_PORT < "${CONFIG_DIR}/ssl_port"
    [ -f "${CONFIG_DIR}/ssl_san" ] && read -r MYMPD_SSL_SAN < "${CONFIG_DIR}/ssl_san"
    [ -f "${CONFIG_DIR}/custom_cert" ] && read -r MYMPD_CUSTOM_CERT < "${CONFIG_DIR}/custom_cert"
    [ -f "${CONFIG_DIR}/ssl_cert" ] && read -r MYMPD_SSL_CERT < "${CONFIG_DIR}/ssl_cert"
    [ -f "${CONFIG_DIR}/ssl_key" ] && read -r MYMPD_SSL_KEY < "${CONFIG_DIR}/ssl_key"
    [ -f "${CONFIG_DIR}/webradiodb" ] && read -r MYMPD_WEBRADIODB < "${CONFIG_DIR}/webradiodb"
}

apply_config() {
    if [ "$MYMPD_SYSTEMD" -eq 1 ]
    then
        systemd-run -p DynamicUser=yes -p StateDirectory=mympd -p CacheDirectory=mympd \
            -E MYMPD_ACL="$MYMPD_ACL" \
            -E MYMPD_ALBUM_GROUP_TAG="$MYMPD_ALBUM_GROUP_TAG" \
            -E MYMPD_ALBUM_MODE="$MYMPD_ALBUM_MODE" \
            -E MYMPD_CACHE_COVER_KEEP_DAYS="$MYMPD_CACHE_COVER_KEEP_DAYS" \
            -E MYMPD_CACHE_LYRICS_KEEP_DAYS="$MYMPD_CACHE_LYRICS_KEEP_DAYS" \
            -E MYMPD_CACHE_MISC_KEEP_DAYS="$MYMPD_CACHE_MISC_KEEP_DAYS" \
            -E MYMPD_CACHE_THUMBS_KEEP_DAYS="$MYMPD_CACHE_THUMBS_KEEP_DAYS" \
            -E MYMPD_LOGLEVEL="$MYMPD_LOGLEVEL" \
            -E MYMPD_URI="$MYMPD_URI" \
            -E MYMPD_SAVE_CACHES="$MYMPD_SAVE_CACHES" \
            -E MYMPD_SCRIPTACL="$MYMPD_SCRIPTACL" \
            -E MYMPD_STICKERS="$MYMPD_STICKERS" \
            -E MYMPD_STICKERS_PAD_INT="$MYMPD_STICKERS_PAD_INT" \
            -E MYMPD_HTTP_HOST="$MYMPD_HTTP_HOST" \
            -E MYMPD_HTTP="$MYMPD_HTTP" \
            -E MYMPD_HTTP_PORT="$MYMPD_HTTP_PORT" \
            -E MYMPD_SSL="$MYMPD_SSL" \
            -E MYMPD_SSL_PORT="$MYMPD_SSL_PORT" \
            -E MYMPD_SSL_SAN="$MYMPD_SSL_SAN" \
            -E MYMPD_CUSTOM_CERT="$MYMPD_CUSTOM_CERT" \
            -E MYMPD_SSL_CERT="$MYMPD_SSL_CERT" \
            -E MYMPD_SSL_KEY="$MYMPD_SSL_KEY" \
            -E MYMPD_WEBRADIODB="$MYMPD_WEBRADIODB" \
            $MYMPD_BIN -c
    else
        export MYMPD_ACL
        export MYMPD_ALBUM_GROUP_TAG
        export MYMPD_ALBUM_MODE
        export MYMPD_CACHE_COVER_KEEP_DAYS
        export MYMPD_CACHE_LYRICS_KEEP_DAYS
        export MYMPD_CACHE_MISC_KEEP_DAYS
        export MYMPD_CACHE_THUMBS_KEEP_DAYS
        export MYMPD_LOGLEVEL
        export MYMPD_URI
        export MYMPD_SAVE_CACHES
        export MYMPD_SCRIPTACL
        export MYMPD_STICKERS
        export MYMPD_STICKERS_PAD_INT
        export MYMPD_HTTP_HOST
        export MYMPD_HTTP
        export MYMPD_HTTP_PORT
        export MYMPD_SSL
        export MYMPD_SSL_PORT
        export MYMPD_SSL_SAN
        export MYMPD_CUSTOM_CERT
        export MYMPD_SSL_CERT
        export MYMPD_SSL_KEY
        export MYMPD_WEBRADIODB
        $MYMPD_BIN -c
    fi
}

set_pin() {
    if [ "$MYMPD_SYSTEMD" -eq 1 ]
    then
        systemd-run -p DynamicUser=yes -p StateDirectory=mympd -p CacheDirectory=mympd \
            mympd -p
    else
        mympd -p
    fi
}

get_input() {
    if INPUT=$(whiptail --clear --cancel-button Cancel --backtitle "$BACKTITLE" --inputbox "$1" 0 "$MENU_WIDTH" -- "$2" \
        3>&1 1>&2 2>&3)
    then
        printf "%s" "$INPUT"
    else
        printf "%s" "$2"
    fi
}

toggle_bool() {
    if [ "$1" = "true" ]
    then
        printf "false"
    else
        printf "true"
    fi
}

menu_webserver() {
    SELECT=$(whiptail --clear --cancel-button "Back" --backtitle "$BACKTITLE" --menu "Webserver" 0 "$MENU_WIDTH" 0 -- \
        "Listening IP" "$MYMPD_HTTP_HOST" \
        "HTTP" "$MYMPD_HTTP" \
        "ACL" "$MYMPD_ACL" \
        "Script ACL" "$MYMPD_SCRIPTACL" \
        "HTTP Port" "$MYMPD_HTTP_PORT" \
        "SSL" "$MYMPD_SSL" \
        "SSL Port" "$MYMPD_SSL_PORT" \
        "SAN" "$MYMPD_SSL_SAN" \
        "Custom certificate" "$MYMPD_CUSTOM_CERT" \
        "Certificate file" "$MYMPD_SSL_CERT" \
        "Private key file" "$MYMPD_SSL_KEY" \
        3>&1 1>&2 2>&3)
    case "$SELECT" in
        "Listening IP") MYMPD_HTTP_HOST=$(get_input "$SELECT" "$MYMPD_HTTP_HOST") ;;
        "HTTP") MYMPD_HTTP=$(toggle_bool "$MYMPD_HTTP") ;;
        "ACL") MYMPD_ACL=$(toggle_bool "$MYMPD_ACL") ;;
        "Script ACL") MYMPD_SCRIPTACL=$(toggle_bool "$MYMPD_SCRIPTACL") ;;
        "HTTP Port") MYMPD_HTTP_PORT=$(get_input "$SELECT" "$MYMPD_HTTP_PORT") ;;
        "SSL") MYMPD_SSL=$(toggle_bool "$MYMPD_SSL") ;;
        "SSL Port") MYMPD_SSL_PORT=$(get_input "$SELECT" "$MYMPD_SSL_PORT") ;;
        "SAN") MYMPD_SSL_SAN=$(get_input "$SELECT" "$MYMPD_SSL_SAN") ;;
        "Custom certificate") MYMPD_CUSTOM_CERT=$(get_input "$SELECT" "$MYMPD_CUSTOM_CERT") ;;
        "Certificate file") MYMPD_SSL_CERT=$(get_input "$SELECT" "$MYMPD_SSL_CERT") ;;
        "Private key file") MYMPD_SSL_KEY=$(get_input "$SELECT" "$MYMPD_SSL_KEY") ;;
        "") return ;;
    esac
    menu_webserver
}

toggle_album_mode() {
    if [ "$1" = "adv" ]
    then
        printf "simple"
    else
        printf "adv"
    fi
}

select_loglevel() {
    case "$1" in
        "0") S_EMERG=1 ;;
        "1") S_ALERT=1 ;;
        "2") S_CRITICAL=1 ;;
        "3") S_ERROR=1 ;;
        "4") S_WARN=1 ;;
        "5") S_NOTICE=1 ;;
        "6") S_INFO=1 ;;
        "7") S_DEBUG=1 ;;
    esac
    if SELECT=$(whiptail --clear --cancel-button "Cancel" --backtitle "$BACKTITLE" --radiolist "Loglevel" 0 "$MENU_WIDTH" 0 -- \
        "0" "Emerg" "$S_EMERG" \
        "1" "Alert" "$S_ALERT" \
        "2" "Critical" "$S_CRITICAL" \
        "3" "Error" "$S_ERROR" \
        "4" "Warn" "$S_WARN" \
        "5" "Notice" "$S_NOTICE" \
        "6" "Info" "$S_INFO" \
        "7" "Debug" "$S_DEBUG" \
        3>&1 1>&2 2>&3)
    then
        printf "%s" "$SELECT"
    else
        printf "%s" "$1"
    fi
}

menu_misc() {
    SELECT=$(whiptail --clear --cancel-button "Back" --backtitle "$BACKTITLE" --menu "Misc" 0 "$MENU_WIDTH" 0 -- \
        "Album group tag" "$MYMPD_ALBUM_GROUP_TAG" \
        "Album mode" "$MYMPD_ALBUM_MODE" \
        "Cover cache" "$MYMPD_CACHE_COVER_KEEP_DAYS" \
        "Lyrics cache" "$MYMPD_CACHE_LYRICS_KEEP_DAYS" \
        "Misc cache" "$MYMPD_CACHE_MISC_KEEP_DAYS" \
        "Thumbs cache" "$MYMPD_CACHE_THUMBS_KEEP_DAYS" \
        "Loglevel" "$MYMPD_LOGLEVEL" \
        "myMPD URI" "$MYMPD_URI" \
        "Save Caches" "$MYMPD_SAVE_CACHES" \
        "Enable stickers" "$MYMPD_STICKERS" \
        "Enable sticker padding" "$MYMPD_STICKERS_PAD_INT" \
        "Enable WebradioDB" "$MYMPD_WEBRADIODB" \
        3>&1 1>&2 2>&3)
    case "$SELECT" in
        "Album group tag") MYMPD_ALBUM_GROUP_TAG=$(get_input "$SELECT" "$MYMPD_ALBUM_GROUP_TAG") ;;
        "Album mode") MYMPD_ALBUM_MODE=$(toggle_album_mode "$MYMPD_ALBUM_MODE") ;;
        "Cover cache") MYMPD_CACHE_COVER_KEEP_DAYS=$(get_input "$SELECT" "$MYMPD_CACHE_COVER_KEEP_DAYS") ;;
        "Lyrics cache") MYMPD_CACHE_LYRICS_KEEP_DAYS=$(get_input "$SELECT" "$MYMPD_CACHE_LYRICS_KEEP_DAYS") ;;
        "Misc cache") MYMPD_CACHE_MISC_KEEP_DAYS=$(get_input "$SELECT" "$MYMPD_CACHE_MISC_KEEP_DAYS") ;;
        "Thumbs cache") MYMPD_CACHE_THUMBS_KEEP_DAYS=$(get_input "$SELECT" "$MYMPD_CACHE_THUMBS_KEEP_DAYS") ;;
        "Loglevel") MYMPD_LOGLEVEL=$(select_loglevel "$MYMPD_LOGLEVEL") ;;
        "myMPD URI") MYMPD_URI=$(get_input "$SELECT" "$MYMPD_URI") ;;
        "Save Caches") MYMPD_SAVE_CACHES=$(toggle_bool "$MYMPD_SAVE_CACHES") ;;
        "Enable stickers") MYMPD_STICKERS=$(toggle_bool "$MYMPD_STICKERS") ;;
        "Enable sticker padding") MYMPD_STICKERS_PAD_INT=$(toggle_bool "$MYMPD_STICKERS_PAD_INT") ;;
        "Enable WebradioDB") MYMPD_WEBRADIODB=$(toggle_bool "$MYMPD_WEBRADIODB") ;;
        "") return ;;
    esac
    menu_misc
}

menu_main() {
    SELECT=$(whiptail --clear --notags --cancel-button "Exit" --backtitle "$BACKTITLE" --menu "$BACKTITLE" 0 "$MENU_WIDTH" 0 -- \
        "W" "Webserver" \
        "M" "Misc" \
        "P" "Set PIN" \
        "R" "Reset to default" \
        "A" "Apply" \
        3>&1 1>&2 2>&3)
    case "$SELECT" in
        "W") menu_webserver ;;
        "M") menu_misc ;;
        "P") set_pin ;;
        "R") set_default ;;
        "A") apply_config ;;
        "") return ;;
    esac
    menu_main
}

parse_options() {
    while [ "$#" -ge 2 ]
    do
        case "$1" in
            MYMPD_ACL) MYMPD_ACL="$2" ;;
            MYMPD_ALBUM_GROUP_TAG) MYMPD_ALBUM_GROUP_TAG="$2" ;;
            MYMPD_ALBUM_MODE) MYMPD_ALBUM_MODE="$2" ;;
            MYMPD_CACHE_COVER_KEEP_DAYS) MYMPD_CACHE_COVER_KEEP_DAYS="$2" ;;
            MYMPD_CACHE_LYRICS_KEEP_DAYS) MYMPD_CACHE_LYRICS_KEEP_DAYS="$2" ;;
            MYMPD_CACHE_MISC_KEEP_DAYS) MYMPD_CACHE_MISC_KEEP_DAYS="$2" ;;
            MYMPD_CACHE_THUMBS_KEEP_DAYS) MYMPD_CACHE_THUMBS_KEEP_DAYS="$2" ;;
            MYMPD_LOGLEVEL) MYMPD_LOGLEVEL="$2" ;;
            MYMPD_URI) MYMPD_URI="$2" ;;
            MYMPD_SAVE_CACHES) MYMPD_SAVE_CACHES="$2" ;;
            MYMPD_SCRIPTACL) MYMPD_SCRIPTACL="$2" ;;
            MYMPD_STICKERS) MYMPD_STICKERS="$2" ;;
            MYMPD_STICKERS_PAD_INT) MYMPD_STICKERS_PAD_INT="$2" ;;
            MYMPD_HTTP_HOST) MYMPD_HTTP_HOST="$2" ;;
            MYMPD_HTTP) MYMPD_HTTP="$2" ;;
            MYMPD_HTTP_PORT) MYMPD_HTTP_PORT="$2" ;;
            MYMPD_SSL) MYMPD_SSL="$2" ;;
            MYMPD_SSL_PORT) MYMPD_SSL_PORT="$2" ;;
            MYMPD_SSL_SAN) MYMPD_SSL_SAN="$2" ;;
            MYMPD_CUSTOM_CERT) MYMPD_CUSTOM_CERT="$2" ;;
            MYMPD_SSL_CERT) MYMPD_SSL_CERT="$2" ;;
            MYMPD_SSL_KEY) MYMPD_SSL_KEY="$2" ;;
            MYMPD_WEBRADIODB) MYMPD_WEBRADIODB="$2" ;;
            *)
                echo "Invalid configuration setting"
                exit 1
                ;;
        esac
        shift
        shift
    done
    apply_config
}

# main
set_default
read_config
if [ "$#" -eq 0 ]
then
    menu_main
else
    parse_options "$@"
fi
exit 0
