#!/bin/bash

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

# Определяем местоположение скрипта
SCRIPT_PATH=$(dirname "$(readlink -f "$0")")
# Импортируем функции
source $SCRIPT_PATH/super_user_check
source $SCRIPT_PATH/astra-mobile-clean-functions
source $SCRIPT_PATH/astra-mobile-clean-and-lock-config

check_root_rights

#==============================================================================
# Возможные результаты детектирования
#==============================================================================
# Выходное значение детектора: "Детектор не сработал"
declare -i NOT_DETECTED=0
# Выходное значение детектора: "Сработал детектор среднего режима"
declare -i MIDDLE_DETECTED=1
# Выходное значение детектора: "Сработал детектор жёсткого режима"
declare -i HARD_DETECTED=2

#==============================================================================
# Функции
#==============================================================================
## @getInterrupt
## @brief - Функция вернёт значение продолжительности прерывания обработки
## @return Вернёт значение продолжительности прерывания обработки
function getInterrupt() {
    # Обработка будет примерно 1 раз в минуту
    echo 60
}

#==============================================================================
# Обработка
#==============================================================================
## @userIsLoggedIn
## @brief - Функция проверит авторизирован ли сейчас указанный пользователь
## @param $1 - Имя пользователя
## @return Вернёт логический признак того что пользователь авторизирован
function userIsLoggedIn() {
    local USER="$1"
    [ ! -z "$(w $USER --no-header)" ]
}
## @userAbsenceToLong
## @brief - Функция вернёт признак того, что пользователь отсутствует в системе дольше чем указанный период времени
## @param $1 - Имя пользователя
## @param $2 - Максимально допустимый период времени отсутствия пользователя в системе (timestamp)
## @return Вернёт логический признак превышения заданного времени отсутствия пользователя в системе
function userAbsenceToLong() {
    local USER="$1"     # string
    local MAX_PERIOD=$2 # uint (timestamp)

#    Возможные сценарии:
#    1) Время входа последней сессии == 0 - Это пользователь ни разу не заходил. (Значит и чистить у него нечего)
#    2) Время входа последней сессии > времени завершения последней сессии - Этот пользователь прямо сейчас работает. (Не трогаем его файлы)
#       - Надёжнее проверять через "who"
#    3) Время входа последней сессии <= времени завершения последней сессии. - Этот пользователь отсутствует. (Проверяем как долго)

    local lastSessionStart=$(userGetLastSessionStart $USER)
    local lastSessionEnd=$(userGetLastSessionEnd $USER)
    local absencePeriod=0

    if [ $lastSessionStart -eq 0 ]; then
        # Зануляем, последнее условие не сработает
        absencePeriod=0
    elif $(userIsLoggedIn "$USER"); then
        # Зануляем, последнее условие не сработает
        absencePeriod=0
    elif [ $lastSessionStart -le $lastSessionEnd ]; then
        # Вычисляем период отсутствия
        absencePeriod=$(( $(date +%s) - $lastSessionEnd ))
    fi

    # Истина если период отсутствия равен или превышает заданный период
    [ $absencePeriod -ge $MAX_PERIOD ]
}

## @onDetected
## @brief - Обработчик события детектирования
## @param $1 - Пользователь
## @param $2 - Тип события
function onDetected() {
    local USER="$1"
    local EVENT_TYPE=$2

    if [ $EVENT_TYPE -eq $MIDDLE_DETECTED ]; then
        echo "[$(date +'%d.%m.%Y %T')] $USER MIDDLE DETECTED!"
        /bin/bash $SCRIPT_PATH/astra-mobile-clean-home "$USER"
    elif [ $EVENT_TYPE -eq $HARD_DETECTED ]; then
        echo "[$(date +'%d.%m.%Y %T')] $USER HARD DETECTED!"
        /bin/bash $SCRIPT_PATH/astra-mobile-clean-device "$USER"
    fi
}

## @detectUserAbsenceToLong
## @brief - Функция детектирования продолжительного отсутствия пользователя в системе
## @param $1 - Имя пользователя
## @param $2 - Максимально допустимый период времени отсутствия пользователя в системе (timestamp)
## @return Вернёт логический признак превышения заданного времени отсутствия пользователя в системе
function detectUserAbsenceToLong() {
    local USER="$1"     # string
    local MAX_PERIOD=$2     # uint (timestamp)

#    На случай если значение периода отсутствия меньше минуты (скорее всего конфиг не инициализирован или повреждён)
    if [ $MAX_PERIOD -lt 60 ]; then
#        Вернём ложь и не будем трогать файлы пользователя
        [ 1 == 0 ]
    else
#        Вернём логическое значение "Пользователь отсутствует слишком долго" = true в противном случаи false
        $(userAbsenceToLong "$USER" "$MAX_PERIOD")
    fi
}

## @detectMiddle
## @brief - Функция детектирования продолжительного отсутствия пользователя в системе (Middle Mode)
## @param $1 - Имя пользователя
## @return Вернёт логический признак превышения заданного времени отсутствия пользователя в системе
function detectMiddle() {
    local USER="$1"
    $(iniGetMiddleModeActive) && $(detectUserAbsenceToLong "$USER" $(iniGetMiddleModeTimeWithoutLogin))
}

## @detectHard
## @brief - Функция детектирования продолжительного отсутствия пользователя в системе (Hard Mode)
## @param $1 - Имя пользователя
## @return Вернёт логический признак превышения заданного времени отсутствия пользователя в системе
function detectHard() {
    local USER="$1"
     $(iniGetHardModeActive) && $(detectUserAbsenceToLong "$USER" $(iniGetHardModeTimeWithoutLogin))
}

## @detector
## @brief - Функция детектирования продолжительного отсутствия пользователя в системе (All Modes)
## @param $1 - Имя пользователя
## @return Вернёт одно из значений детектора (MIDDLE_DETECTED|HARD_DETECTED|NOT_DETECTED)
function detector() {
    local USER="$1"
    local outResult=$NOT_DETECTED

    # Hard может перекрывать Middle

    if $(detectMiddle "$USER"); then
        outResult=$MIDDLE_DETECTED
    fi

    if $(detectHard "$USER"); then
        outResult=$HARD_DETECTED
    fi

    return $outResult
}

## detectIteration
## @brief - Функция выполнит итерацию детектирования
function detectIteration() {
    # Запросим список пользователей системы
     declare -a Users
     userList Users

    # Обрабатываем данные для всех пользователей
    for User in ${Users[@]}
    do
        # Пропустим системных пользователей
        if [ $(id -u "$User") -lt 1000 ]; then continue; fi
        # Получим домашнюю директорию пользователя
        local HomeDir=$(userGetHomeDir $User)

        # Рассматриваем только пользователя с домашней директорией
        if [ -d "$HomeDir" ]; then
            # Запускаем детектор
            detector "$User"
            detectResult=$?
            # Проверяем результат выполнения
            if [[ "$detectResult" != @($NOT_DETECTED) ]]; then
                # Обрабатываем событие детектирования
                onDetected "$User" $detectResult
            fi
        fi
    done
}

## @loop
## @brief - Функция циклического детектирования
function loop() {
    while [ 1 ]
    do
        # Выполняем итерацию детектирования
        detectIteration
        # Прерывание обработки
        sleep $(getInterrupt)
    done
}

#==============================================================================
# Main
#==============================================================================
# Запускаем цикл обработки
loop
#==============================================================================
