<?php
/**
 * 디스크 사용량 감시 + 캐시 자동 정리
 * [SHOP-ONLY] IKEv2 서버 crontab에는 등록하지 않음
 *
 * 동작:
 *  - list_page 캐시: 항상 10분(600초) 이상 된 파일 삭제, 300개 이하 유지
 *  - 디스크 사용률 85% 초과: list_page 파일 전체 삭제
 *  - 디스크 사용률 92% 초과: data/cache 내 만료된 파일 모두 삭제
 *  - 디스크 사용률 95% 초과: data/cache 내 모든 파일 삭제 (긴급)
 */

define('CACHE_DIR',      '/var/www/html/html_VPNLink/data/cache');
define('LIST_PAGE_DIR',  CACHE_DIR . '/list_page');
define('MAX_FILES',      300);    // list_page 최대 유지 파일 수
define('EXPIRE_SECS',    600);    // 10분 이상 된 파일은 만료로 간주
define('DISK_WARN',      85);     // % - list_page 전체 삭제 기준
define('DISK_HIGH',      92);     // % - cache 내 만료 파일 삭제
define('DISK_CRITICAL',  95);     // % - cache 전체 긴급 삭제

$log_prefix = '[cache_disk_guard ' . date('Y-m-d H:i:s') . '] ';

// ── 1. 디스크 사용률 확인 ──────────────────────────────────────────────
$disk_total = disk_total_space(CACHE_DIR);
$disk_free  = disk_free_space(CACHE_DIR);
$disk_pct   = ($disk_total > 0) ? (int)round(($disk_total - $disk_free) / $disk_total * 100) : 0;

// ── 2. list_page: 만료된 파일 + 최대 파일 수 초과분 삭제 ──────────────
$deleted_expired  = 0;
$deleted_overflow = 0;

if (is_dir(LIST_PAGE_DIR)) {
    $now   = time();
    $files = glob(LIST_PAGE_DIR . '/*.html');
    if (is_array($files)) {
        // 만료된 파일 삭제
        foreach ($files as $f) {
            if (($now - (int)@filemtime($f)) > EXPIRE_SECS) {
                if (@unlink($f)) {
                    $deleted_expired++;
                }
            }
        }
        // 파일 수 제한
        $files = glob(LIST_PAGE_DIR . '/*.html');
        if (is_array($files) && count($files) > MAX_FILES) {
            usort($files, function($a, $b) { return filemtime($a) - filemtime($b); });
            $over = count($files) - MAX_FILES;
            for ($i = 0; $i < $over; $i++) {
                if (@unlink($files[$i])) {
                    $deleted_overflow++;
                }
            }
        }
        $remaining = count(glob(LIST_PAGE_DIR . '/*.html') ?: []);
        echo $log_prefix . "list_page 정리: 만료 {$deleted_expired}개 삭제, 초과 {$deleted_overflow}개 삭제, 잔여 {$remaining}개 (disk={$disk_pct}%)\n";
    }
}

// ── 3. 디스크 임계값별 추가 조치 ──────────────────────────────────────
if ($disk_pct >= DISK_CRITICAL) {
    // 긴급: list_page 전체 + CSS/HTML 캐시 전체 삭제
    echo $log_prefix . "긴급({$disk_pct}%) - data/cache 파일 전체 삭제 시작\n";
    _delete_dir_files(LIST_PAGE_DIR);
    _delete_dir_files(CACHE_DIR . '/CSS');
    _delete_dir_files(CACHE_DIR . '/HTML');
    // login_guard, optimize_run lock 파일은 유지 (비교적 작음)
    echo $log_prefix . "긴급 삭제 완료\n";

} elseif ($disk_pct >= DISK_HIGH) {
    // 고위: cache 하위 만료 파일 전체 제거
    echo $log_prefix . "고위({$disk_pct}%) - cache 전체에서 만료 파일 제거\n";
    _delete_expired_in_dir(CACHE_DIR . '/CSS', 86400);   // 1일
    _delete_expired_in_dir(CACHE_DIR . '/HTML', 86400);  // 1일
    echo $log_prefix . "고위 정리 완료\n";

} elseif ($disk_pct >= DISK_WARN) {
    // 경고: list_page 전체 삭제
    echo $log_prefix . "경고({$disk_pct}%) - list_page 전체 삭제\n";
    _delete_dir_files(LIST_PAGE_DIR);
    echo $log_prefix . "경고 삭제 완료\n";
}

// 현재 디스크 상황을 다시 확인해서 출력
$disk_free_after = disk_free_space(CACHE_DIR);
$disk_pct_after  = ($disk_total > 0) ? (int)round(($disk_total - $disk_free_after) / $disk_total * 100) : 0;
echo $log_prefix . "완료 - disk={$disk_pct_after}% (여유 " . _human_bytes($disk_free_after) . ")\n";

// ── 헬퍼 ──────────────────────────────────────────────────────────────
function _delete_dir_files($dir) {
    if (!is_dir($dir)) return 0;
    $cnt = 0;
    foreach (glob($dir . '/*') as $f) {
        if (is_file($f) && @unlink($f)) {
            $cnt++;
        }
    }
    return $cnt;
}

function _delete_expired_in_dir($dir, $expire_secs) {
    if (!is_dir($dir)) return 0;
    $now = time();
    $cnt = 0;
    foreach (glob($dir . '/*') as $f) {
        if (is_file($f) && ($now - (int)@filemtime($f)) > $expire_secs) {
            if (@unlink($f)) $cnt++;
        }
    }
    return $cnt;
}

function _human_bytes($bytes) {
    if ($bytes >= 1073741824) return round($bytes / 1073741824, 1) . 'GB';
    if ($bytes >= 1048576)    return round($bytes / 1048576, 1) . 'MB';
    return round($bytes / 1024, 0) . 'KB';
}
