<?
class i_disk_working
{
    // Универсальный метод для проверки директорий с превышением срока хранения
    public static function check_storage($options)
    {
        ob_start() ;

        $dir_path = $options['dir_path'];
        $setting_name = $options['setting_name'];
        $title = $options['title'];
        $delete_action = $options['delete_action'];
        $button_text = $options['button_text'];
        $log_name = isset($options['log_name']) ? $options['log_name'] : 'disk_working';

        ?><h2><?echo $title?></h2><?

        if (!is_dir($dir_path))
        {
            echo '<div class="alert">Директория '.$dir_path.' не найдена</div>';
            $text=ob_get_clean() ;
            echo $text ;
            return;
        }

        // Получаем срок хранения из настроек
        $storage_time_days = isset($GLOBALS[$setting_name]) ? (int)$GLOBALS[$setting_name] : 0;

        if ($storage_time_days <= 0)
        {
            echo '<div class="alert">Срок хранения не задан в настройках ('.$setting_name.')</div>';
            $text=ob_get_clean() ;
            echo $text ;
            return;
        }

        echo 'Срок хранения: <strong>'.$storage_time_days.'</strong> дней<br><br>';

        // Вычисляем дату, до которой должны храниться директории
        $cutoff_timestamp = time() - ($storage_time_days * 24 * 60 * 60);
        $cutoff_date = date('Y-m-d H:i:s', $cutoff_timestamp);

        echo 'Директории, измененные ранее <strong>'.$cutoff_date.'</strong>, будут помечены на удаление<br><br>';

        // Получаем список директорий первого уровня
        $dirs_to_delete = array();
        $all_dirs = array();

        // Проверяем директории первого уровня
        $items = scandir($dir_path);
        foreach ($items as $item)
        {
            if ($item == '.' || $item == '..') continue;

            $item_path = $dir_path.'/'.$item;
            if (is_dir($item_path))
            {
                $mtime = filemtime($item_path);
                $age_str = self::format_age($mtime);

                $all_dirs[] = array(
                    'path' => $item_path,
                    'rel_path' => $item,
                    'mtime' => $mtime,
                    'mtime_str' => date('Y-m-d H:i:s', $mtime),
                    'age_str' => $age_str
                );

                if ($mtime < $cutoff_timestamp)
                {
                    $dirs_to_delete[] = $item;
                }
            }
        }

        $total_dirs = count($all_dirs);
        $dirs_to_delete_count = count($dirs_to_delete);

        echo 'Всего найдено директорий: <strong>'.$total_dirs.'</strong><br>';
        echo 'Директорий на удаление: <strong>'.$dirs_to_delete_count.'</strong><br><br>';

        if ($dirs_to_delete_count > 0)
        {
            ?><h3>Список директорий на удаление:</h3>
            <table class="basic fz_small auto">
                <tr>
                    <th>Директория</th>
                    <th>Дата изменения</th>
                    <th>Срок давности</th>
                </tr><?
            foreach ($all_dirs as $dir_info)
            {
                if (in_array($dir_info['rel_path'], $dirs_to_delete))
                {
                    ?><tr>
                        <td class="left"><?echo htmlspecialchars($dir_info['rel_path'])?></td>
                        <td><?echo $dir_info['mtime_str']?></td>
                        <td><?echo $dir_info['age_str']?></td>
                    </tr><?
                }
            }
            ?></table><br><?

            // Сохраняем список директорий для удаления во временный файл
            $temp_file = _DIR_TO_ROOT.'/temp/'.$delete_action.'_dirs_to_delete_'.ENGINE()->generate_UID().'.json';
            file_put_contents($temp_file, json_encode($dirs_to_delete));
            $temp_file_name = basename($temp_file);

            ?><button class="v1"
                      href="/cab/setting/update/check_systems/[check_cmd=check_disk,action=<?echo $delete_action?>,dirs_file=<?echo $temp_file_name?>]/"
                      cmd_method="v1"><?echo $button_text?></button><?
        }
        else
        {
            echo '<div class="green">Директорий с превышенным сроком хранения не найдено</div>';
        }
        $text=ob_get_clean() ;
        LOGS()->reg_log($log_name, $delete_action, ['save_to_file'=>$text]) ;
        echo $text ;
    }

    // Обертки для конкретных директорий
    public static function check_mo_photo_storage($filter)
    {
        self::check_storage(array(
            'dir_path' => _DIR_TO_ROOT.'/public/mo_photo',
            'setting_name' => 'LS_mo_photo_storage_time',
            'title' => 'Проверка директорий фото МО с превышением срока хранения',
            'delete_action' => 'delete_mo_photo_storage',
            'button_text' => 'Удалить фото с превышенным сроком хранения',
            'log_name' => 'delete_old_mo_photo'
        ));
    }

    public static function check_mo_sign_storage($filter)
    {
        self::check_storage(array(
            'dir_path' => _DIR_TO_ROOT.'/public/mo_sign',
            'setting_name' => 'LS_mo_dsign_storage_time',
            'title' => 'Проверка директорий цифровых слепков подписей МО с превышением срока хранения',
            'delete_action' => 'delete_mo_sign_storage',
            'button_text' => 'Удалить цифровые слепки подписей с превышенным сроком хранения'
        ));
    }

    public static function check_mo_sign_image_storage($filter)
    {
        self::check_storage(array(
            'dir_path' => _DIR_TO_ROOT.'/public/mo_sign_image',
            'setting_name' => 'LS_mo_sign_storage_time',
            'title' => 'Проверка директорий изображений подписей МО с превышением срока хранения',
            'delete_action' => 'delete_mo_sign_image_storage',
            'button_text' => 'Удалить изображения подписей с превышенным сроком хранения'
        ));
    }

    public static function show_disk_info()
    {
        ?><h2>Информация о свободном месте на диске</h2><?

        $df_output = shell_exec('df -h 2>&1');
        if ($df_output)
        {
            ?><pre data-enlighter-language="text"><?echo htmlspecialchars($df_output)?></pre><?
        }
        else
        {
            echo '<div class="alert">Не удалось получить информацию о диске</div>';
        }
    }

    // Универсальный метод для удаления директорий
    public static function delete_storage($options = array())
    {
        $dir_path = $options['dir_path'];
        $title = $options['title'];

        FILE_LOG()->append('Начало удаления: '.$title, 1);

        if (!is_dir($dir_path))
        {
            FILE_LOG()->append('ОШИБКА: Директория '.$dir_path.' не найдена', 1);
            return;
        }

        // Получаем список директорий для удаления из файла или параметров
        $dirs_to_delete = array();

        if (isset($options['dirs_file']) && $options['dirs_file'])
        {
            $temp_file = _DIR_TO_ROOT.'/temp/'.$options['dirs_file'];
            if (file_exists($temp_file))
            {
                $dirs_to_delete = json_decode(file_get_contents($temp_file), true);
                if (!is_array($dirs_to_delete)) $dirs_to_delete = array();
            }
        }
        elseif (isset($options['dirs']) && is_array($options['dirs']))
        {
            $dirs_to_delete = $options['dirs'];
        }

        if (empty($dirs_to_delete))
        {
            FILE_LOG()->append('Список директорий для удаления пуст', 1);
            return;
        }

        FILE_LOG()->append('Найдено директорий для удаления: '.count($dirs_to_delete), 1);

        // Выполняем команду df до удаления
        echo '<div class="alert"><strong>Размер диска ДО удаления</strong></div>' ;

        $du_before = shell_exec('df -h 2>&1');
        if ($du_before) echo '<pre data-enlighter-language="text">'.htmlspecialchars($du_before).'</pre>' ;
        else echo 'Не удалось выполнить "df -h"<br>' ;


        $deleted_count = 0;
        $errors = array();

        foreach ($dirs_to_delete as $rel_path)
        {
            $full_path = $dir_path.'/'.$rel_path;

            if (is_dir($full_path))
            {
                // Удаляем директорию рекурсивно
                if (self::delete_directory($full_path))
                {
                    FILE_LOG()->append('Успешно удалена директория: '.$rel_path, 1);
                    $deleted_count++;
                }
                else
                {
                    $error_msg = 'Ошибка при удалении директории: '.$rel_path;
                    FILE_LOG()->append('ОШИБКА: '.$error_msg, 1);
                    $errors[] = $error_msg;
                }
            }
            else
            {
                $error_msg = 'Директория не найдена: '.$rel_path.' ['.$full_path.']';
                FILE_LOG()->append('ПРЕДУПРЕЖДЕНИЕ: '.$error_msg, 1);
            }
        }

        // Выполняем команду df после удаления
        echo '<div class="alert"><strong>Размер диска ПОСЛЕ удаления</strong></div>' ;
        $du_after = shell_exec('df -h 2>&1');
        if ($du_after) echo '<pre data-enlighter-language="text">'.htmlspecialchars($du_after).'</pre>' ;
        else echo 'Не удалось выполнить "df -h"<br>' ;

        FILE_LOG()->append('Удалено директорий: '.$deleted_count.' из '.count($dirs_to_delete), 1);

        if (!empty($errors))
        {
            FILE_LOG()->append('Ошибок при удалении: '.count($errors), 1);
        }

        // Удаляем временный файл со списком директорий
        if (isset($options['dirs_file']) && $options['dirs_file'])
        {
            $temp_file = _DIR_TO_ROOT.'/temp/'.$options['dirs_file'];
            if (file_exists($temp_file))
            {
                @unlink($temp_file);
            }
        }
    }

    // Обертки для конкретных директорий
    public static function delete_mo_photo_storage($options = array())
    {
        $options['dir_path'] = _DIR_TO_ROOT.'/public/mo_photo';
        $options['title'] = 'Удаление директорий фото МО с превышенным сроком хранения';
        self::delete_storage($options);
    }

    public static function delete_mo_sign_storage($options = array())
    {
        $options['dir_path'] = _DIR_TO_ROOT.'/public/mo_sign';
        $options['title'] = 'Удаление директорий цифровых слепков подписей МО с превышенным сроком хранения';
        self::delete_storage($options);
    }

    public static function delete_mo_sign_image_storage($options = array())
    {
        $options['dir_path'] = _DIR_TO_ROOT.'/public/mo_sign_image';
        $options['title'] = 'Удаление директорий изображений подписей МО с превышенным сроком хранения';
        self::delete_storage($options);
    }

    private static function delete_directory($dir)
    {
        if (!is_dir($dir))
        {
            return false;
        }

        $files = array_diff(scandir($dir), array('.', '..'));

        foreach ($files as $file)
        {
            $file_path = $dir.'/'.$file;

            if (is_dir($file_path))
            {
                self::delete_directory($file_path);
            }
            else
            {
                @unlink($file_path);
            }
        }

        return @rmdir($dir);
    }

    private static function format_bytes($bytes, $precision = 2)
    {
        $units = array('B', 'KB', 'MB', 'GB', 'TB');

        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);

        $bytes /= pow(1024, $pow);

        return round($bytes, $precision).' '.$units[$pow];
    }

    private static function format_age($timestamp)
    {
        $now = time();
        $diff = $now - $timestamp;

        if ($diff < 0) return '0 '.get_case_by_count_1_2_5(0, 'день,дня,дней');

        $years = floor($diff / (365 * 24 * 60 * 60));
        $months = floor(($diff % (365 * 24 * 60 * 60)) / (30 * 24 * 60 * 60));
        $days = floor(($diff % (30 * 24 * 60 * 60)) / (24 * 60 * 60));

        $parts = array();

        if ($years > 0)
        {
            $parts[] = $years.' '.get_case_by_count_1_2_5($years, 'год,года,лет');
        }

        if ($months > 0)
        {
            $parts[] = $months.' '.get_case_by_count_1_2_5($months, 'месяц,месяца,месяцев');
        }

        if ($days > 0 || empty($parts))
        {
            $parts[] = $days.' '.get_case_by_count_1_2_5($days, 'день,дня,дней');
        }

        return implode(', ', $parts);
    }
}

?>

