<?php
/**
 * SecurityHelper - Bảo mật cho hệ thống Backup & Restore
 */

if (!defined('ABSPATH')) {
    exit;
}

class Foxblock_Backup_SecurityHelper
{
    const BACKUP_DIR_NAME = 'foxblock_backup';
    const MAX_UPLOAD_SIZE = 536870912000; // 500GB (Không giới hạn thực tế)

    /**
     * Kiểm tra quyền và nonce AJAX
     */
    public static function check_ajax_permission()
    {
        check_ajax_referer('foxblock_nonce', 'nonce');
        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => 'Bạn không có quyền thực hiện thao tác này.'], 403);
        }
    }

    /**
     * Lấy đường dẫn thư mục backup, tạo nếu chưa tồn tại
     */
    public static function get_backup_dir()
    {
        $upload_dir = wp_upload_dir();
        // Lưu ngoài uploads để tránh truy cập web trực tiếp dễ hơn
        $backup_dir = WP_CONTENT_DIR . '/' . self::BACKUP_DIR_NAME;

        if (!file_exists($backup_dir)) {
            wp_mkdir_p($backup_dir);
            self::secure_directory($backup_dir);
        }

        return $backup_dir;
    }

    /**
     * Bảo vệ thư mục backup bằng .htaccess và index.php
     */
    public static function secure_directory($dir)
    {
        // .htaccess: chặn tất cả truy cập trực tiếp
        $htaccess = $dir . '/.htaccess';
        if (!file_exists($htaccess)) {
            $content = "Options -Indexes\n";
            $content .= "Deny from all\n";
            $content .= "<Files ~ \"\.php$\">\n";
            $content .= "    Deny from all\n";
            $content .= "</Files>\n";
            file_put_contents($htaccess, $content);
        }

        // index.php: fallback bảo vệ
        $index = $dir . '/index.php';
        if (!file_exists($index)) {
            file_put_contents($index, "<?php\n// Silence is golden.\nexit;\n");
        }
    }

    /**
     * Validate file backup được upload
     */
    public static function validate_upload($file_tmp, $file_name, $file_size)
    {
        // Kiểm tra extension
        $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
        if ($ext !== 'foxblock') {
            return ['valid' => false, 'error' => 'File phải có định dạng .foxblock'];
        }

        // Không giới hạn kích thước (chỉ chặn quá lớn bằng config server nếu có)
        // if ($file_size > self::MAX_UPLOAD_SIZE) {
        //     return ['valid' => false, 'error' => 'File quá lớn'];
        // }

        if ($file_size < 100) {
            return ['valid' => false, 'error' => 'File không hợp lệ (quá nhỏ)'];
        }

        // Kiểm tra magic bytes (header signature của foxblock format)
        $fh = fopen($file_tmp, 'rb');
        if (!$fh) {
            return ['valid' => false, 'error' => 'Không thể đọc file'];
        }

        $magic = fread($fh, 8);
        fclose($fh);

        if (substr($magic, 0, 8) !== 'FOXBLOCK') {
            return ['valid' => false, 'error' => 'File không đúng định dạng Foxblock'];
        }

        return ['valid' => true];
    }

    /**
     * Tạo token download an toàn (dùng transient)
     */
    public static function create_download_token($filename)
    {
        $token = wp_generate_password(32, false);
        set_transient('foxblock_dl_' . $token, $filename, 60 * 5); // 5 phút
        return $token;
    }

    /**
     * Xác thực token download
     */
    public static function verify_download_token($token)
    {
        $token = sanitize_text_field($token);
        $filename = get_transient('foxblock_dl_' . $token);
        if ($filename) {
            delete_transient('foxblock_dl_' . $token);
            return $filename;
        }
        return false;
    }

    /**
     * Làm sạch thư mục temp
     */
    public static function cleanup_temp_dir($dir)
    {
        if (empty($dir) || !is_dir($dir)) return;

        // Chỉ cho phép xóa trong thư mục foxblock_temp
        if (strpos(wp_normalize_path($dir), 'foxblock_temp') === false) return;

        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($files as $f) {
            if ($f->isDir()) {
                rmdir($f->getRealPath());
            } else {
                unlink($f->getRealPath());
            }
        }

        rmdir($dir);
    }
}
