#!/bin/bash

#================================================================================
# Инициализация
#================================================================================

# Определяем местоположение скрипта
SCRIPT_PATH=$(dirname "$(readlink -f "$0")")

# Проверяем права суперпользователя
if [[ $EUID -eq 0 ]]; then
        echo -e "Please run the script as a normal user, not as root."
        exit 1
fi

# Время ожидания запуска приложения (в миллисекундах)
APPLICATION_WAIT_TIME=10000

# Интерфейс DBus
EVENTS_INTERFACE='ru.astralinux.events'
# Отправляемый сигнал запуска сесcии waydroid
SIGNAL_WAYDROID_START_SESSION='waydroid_start_session'
# Отправляемый сигнал запуска сесcии waydroid и запуска приложения
SIGNAL_WAYDROID_START_SESSION_AND_LAUNCH='waydroid_start_session_and_launch'

# Получаемый сигнал ожидания запуска приложения waydroid
SIGNAL_WAYDROID_WAIT_APP_LAUNCH='waydroid_wait_app_launch'
# Получаемый сигнал сесcии waydroid с последующим запуском приложения
SIGNAL_WAYDROID_RESTART_SESSION_AND_LAUNCH='waydroid_restart_session_and_launch'

# Получаемый сигнал открытия url в браузере хоста
SIGNAL_OPEN_URL='waydroid_open_url'

# Действие завершения чтения сигнала
ACTION_EXIT=0
# Действие чтение сигнала
ACTION_READ_SIGNAL=1
# Действие чтения аргументов сигнала
ACTION_READ_ARGS=2

# Имя скрипта ожидания запуска приложения
WAIT_APP_SCRIPT_NAME='astra-mobile-waydroid-wait-app'
# Путьт к скрипту ожидания запуска приложения
WAIT_APP_SCRIPT_PATH="$SCRIPT_PATH/$WAIT_APP_SCRIPT_NAME"
# Имя скрипта запуска RTSP камер
START_RTSP_SCRIPT_NAME='astra-mobile-waydroid-start-rtsp'
# Путьт к скрипту запуска RTSP камер
START_RTSP_SCRIPT_PATH="$SCRIPT_PATH/$START_RTSP_SCRIPT_NAME"

#================================================================================
# Функции
#================================================================================
## killByPid
## @brief - Функция убъёт процесс и его подпроцессы по pid
## @param $1 - pid
function killByPid() {
    local PID=$1

    if ps -p $PID > /dev/null 2>&1; then
        for subPID in `ps -ef| awk '$3 == '${PID}' { print $2 }'`
        do
            kill -9 $subPID
        done
        kill -9 $PID
    fi
}

## killByPidFile
## @brief - Функция убъёт процесс по pid из файла
## @param $1 - Путь к файлу
function killByPidFile() {
    local PID_FILE_PATH="$1"

    if [ -f "$PID_FILE_PATH" ]; then
        local PID=$(cat "$PID_FILE_PATH")

        killByPid $PID
        rm "$PID_FILE_PATH"
    fi
}

## isWaydroidStartSessionSignal
## @brief - Функция проверит является ли строка сигналом запуска сессии waydroid
## @param $1 - Проверяемая строка
## @return Вернёт признак получения сигнала запуска сессии waydroid
function isWaydroidStartSessionSignal() {
    local SIGNAL="$1"
    [[ "$SIGNAL" == *"member=$SIGNAL_WAYDROID_START_SESSION"* ]]
}

## isWaydroidStartSessionAndLaunchSignal
## @brief - Функция проверит является ли строка сигналом запуска сессии waydroid и запуска приложения
## @param $1 - Проверяемая строка
## @return Вернёт признак получения сигнала запуска сессии waydroid и запуска приложения
function isWaydroidStartSessionAndLaunchSignal() {
    local SIGNAL="$1"
    [[ "$SIGNAL" == *"member=$SIGNAL_WAYDROID_START_SESSION_AND_LAUNCH"* ]]
}

## isWaydroidWaitAppSignal
## @brief - Функция проверит является ли строка сигналом ожидания запуска приложения waydroid
## @param $1 - Проверяемая строка
## @return Вернёт признак получения сигнала ожидания запуска приложени waydroid
function isWaydroidWaitAppSignal() {
    local SIGNAL="$1"
    [[ "$SIGNAL" == *"member=$SIGNAL_WAYDROID_WAIT_APP_LAUNCH"* ]]
}

## isWaydroidRestartSessionAndLaunchSignal
## @brief - Функция проверит является ли строка сигналом перезапуска сессии waydroid и запуска приложения
## @param $1 - Проверяемая строка
## @return Вернёт признак получения сигнала перезапуска сессии waydroid и запуска приложения
function isWaydroidRestartSessionAndLaunchSignal() {
    local SIGNAL="$1"
    [[ "$SIGNAL" == *"member=$SIGNAL_WAYDROID_RESTART_SESSION_AND_LAUNCH"* ]]
}

## isOpenUrlSignal
## @brief - Функция проверит является ли строка сигналом открытия url в браузере хоста
## @param $1 - Проверяемая строка
## @return Вернёт признак получения сигнала открытия url
function isOpenUrlSignal() {
    local SIGNAL="$1"
    [[ "$SIGNAL" == *"member=$SIGNAL_OPEN_URL"* ]]
}


## getArg
## @brief - Функция извлечёт значение аргумента DBus
## @param $1 - Аргумент в формате DBus
## @return Вернёт значение аргумента
function getArg() {
    local ARG_LINE="$1"
    local out_arg=''

    local regex='string "(.*?)"'
    # Если строка включает соответствие шаблону
    if [[ $line =~ $regex ]]; then
        # Читаем строку
        out_arg="${BASH_REMATCH[1]}"
    else
        # Читаем нечто отличное от строки
        local regex='^.* (.*)'
        if [[ $line =~ $regex ]]; then
            out_arg="${BASH_REMATCH[1]}"
        fi
    fi

    echo "$out_arg"
}

## waitSignal
## @brief - Функция ожидающая сигнал DBus
## @param $1 - Возвращаемое имя сигнала
## @param $2 - Возвращаемый список аргументов сигнала
## @return Вернёт имя полученного сигнала
function waitSignal() {
    declare -n OUT_SIGNAL_NAME=$1
    declare -n OUT_ARGS=$2

    local action=$ACTION_READ_SIGNAL
    local args_count=0
    local out_signal_name=''
    # Построчно читаем данные с DBus
    while IFS= read -ru3 line || [ -n "$line" ]; do
        case $action in
        # Режим ожидания сигнала
        $ACTION_READ_SIGNAL)
            if $(isWaydroidStartSessionAndLaunchSignal "$line"); then
                OUT_SIGNAL_NAME="$SIGNAL_WAYDROID_START_SESSION_AND_LAUNCH"
                args_count=1
                action=$ACTION_READ_ARGS
            elif $(isWaydroidStartSessionSignal "$line"); then
                OUT_SIGNAL_NAME="$SIGNAL_WAYDROID_START_SESSION"
                args_count=0
                action=$ACTION_EXIT
            elif $(isWaydroidRestartSessionAndLaunchSignal "$line"); then
                OUT_SIGNAL_NAME="$SIGNAL_WAYDROID_RESTART_SESSION_AND_LAUNCH"
                args_count=1
                action=$ACTION_READ_ARGS
            elif $(isWaydroidWaitAppSignal "$line"); then
                OUT_SIGNAL_NAME="$SIGNAL_WAYDROID_WAIT_APP_LAUNCH"
                args_count=1
                action=$ACTION_READ_ARGS
            elif $(isOpenUrlSignal "$line"); then
                OUT_SIGNAL_NAME="$SIGNAL_OPEN_URL"
                args_count=1
                action=$ACTION_READ_ARGS
            fi
            ;;
        # Режим чтения аргументов сигнала
        $ACTION_READ_ARGS)
            OUT_ARGS[${#OUT_ARGS[*]}]=$(getArg "$line")
            args_count=$((args_count-1))
            if [ $args_count -le 0 ]; then action=$ACTION_EXIT; fi
            ;;
        # Что-что пошло не так
        *)
            action=$ACTION_EXIT;
            ;;
        esac

        # Завершаем чтение
        if [ "$action" = "$ACTION_EXIT" ]; then
            break;
        fi
    done 3< <(
        dbus-monitor --system "interface=$EVENTS_INTERFACE"
    )
}

## waydroidStopSession
## @brief - Функция остановит сессию waydroid
function waydroidStopSession {
     waydroid session stop 2>&1
}

## waydroidStartSession
## @brief - Функция запустит сессию waydroid
function waydroidStartSession() {
    local SESSION_LOG_PATH='/tmp/waydroid-session'

    waydroid session start  > "$SESSION_LOG_PATH" 2>&1 &
    local try=60

    while [ $try -gt 0 ]; do
        if grep -q "ready" "$SESSION_LOG_PATH" ; then
            break
        fi

        echo "."
        try=$((try-1))
        sleep 1
    done

    if [ $try -gt 0 ]; then
        echo "Waydroid session successfully started!"
        return 0
    else
        waydroidStopSession
        echo "Failed to start waydroid session!"
        return 1
    fi
}

## waydroidLaunchApp
## @brief - Функция запуска приложения waydroid
## @param $1 - Имя приложения waydroid
function waydroidLaunchApp() {
    local APP_NAME="$1"

    if [ ! -z "$APP_NAME" ]; then
        waydroid app launch "$APP_NAME"
    fi
}

## waydroidStartSessionAndLaunch
## @brief - Функция запустит сессию waydroid и приложение
## @param $1 - Имя запускаемого приложения
function waydroidStartSessionAndLaunch() {
    # Выполняем запуск сессии
    waydroidStartSession

    if [[ $? -eq 0 ]]; then
        # Запускаем приложение
        waydroidLaunchApp "$1"
    fi
}

## waydroidRestartSessionAndLaunch
## @brief - Функция перезапустит сессию waydroid и приложение
## @param $1 - Имя запускаемого приложения
function waydroidRestartSessionAndLaunch() {
    # Выполняем остановку сесси
    waydroidStopSession
    # Выполняем запуск
    waydroidStartSessionAndLaunch "$1"
}

## openUrl
## @brief - Функция откроет url в дефолтном браузере
## @param $1 - URL
function openUrl() {
    local URL="$1"

    if [ ! -z "$URL" ]; then
        xdg-open "$URL" &
    fi
}

## main
## @brief - Первичная функция
function main() {
    while [ 1 ]
    do
        local signal=''
        local args=()
        # Ожидаем сигнал
        waitSignal signal args

        echo "$signal ${args[0]}"

        if [ "$signal" = "$SIGNAL_WAYDROID_START_SESSION" ]; then
            killByPidFile '/tmp/waydroidwaitapp.pid'
            killByPidFile '/tmp/waydroidrtsp.pid'
            killByPidFile '/tmp/waydroidsessionstart.pid'
            # Выполняем запуск сессии
            waydroidStartSession &
            echo $! > '/tmp/waydroidsessionstart.pid'
        elif [ "$signal" = "$SIGNAL_WAYDROID_START_SESSION_AND_LAUNCH" ]; then
            killByPidFile '/tmp/waydroidwaitapp.pid'
            killByPidFile '/tmp/waydroidrtsp.pid'
            killByPidFile '/tmp/waydroidsessionstart.pid'
            # Выполняем запуск
            waydroidStartSessionAndLaunch "${args[0]}" &
            echo $! > '/tmp/waydroidsessionstart.pid'
        elif [ "$signal" = "$SIGNAL_WAYDROID_RESTART_SESSION_AND_LAUNCH" ]; then
            killByPidFile '/tmp/waydroidwaitapp.pid'
            killByPidFile '/tmp/waydroidrtsp.pid'
            killByPidFile '/tmp/waydroidsessionstart.pid'
            # Выполняем перезапуск
            waydroidRestartSessionAndLaunch "${args[0]}" &
            echo $! > '/tmp/waydroidsessionstart.pid'
        elif [ "$signal" = "$SIGNAL_WAYDROID_WAIT_APP_LAUNCH" ]; then
            # Ожидаем запуска приложения
            killByPidFile '/tmp/waydroidwaitapp.pid'
            /bin/bash "$WAIT_APP_SCRIPT_PATH" "${args[0]}" "$APPLICATION_WAIT_TIME" &
            echo $! > '/tmp/waydroidwaitapp.pid'

            # При необходимости запускаем RTSP камеру
            killByPidFile '/tmp/waydroidrtsp.pid'
            /bin/bash "$START_RTSP_SCRIPT_PATH" "${args[0]}" "$APPLICATION_WAIT_TIME" &
            echo $! > '/tmp/waydroidrtsp.pid'
        elif [ "$signal" = "$SIGNAL_OPEN_URL" ]; then
            openUrl "${args[0]}"
        fi
    done
}

#==============================================================================
main
exit 0
#================================================================================
