"""
Unit tests for Poe2GraphicsOptimizer (src/assistant_tool/graphics_optimizer.py)
=============================================================================
Kiểm thử toàn diện các chức năng:
1. Đọc và nhận diện file cấu hình.
2. Sao lưu an toàn (.bak) và phục hồi hoàn hảo (restore).
3. Áp dụng các profile: ultra_low (Potato Mode), low_1080p.
4. Bảo toàn nguyên vẹn các section ngoài scope ([LOGIN], [ACTION_KEYS], [UI]).
5. Bảo toàn các key đặc biệt (.gamepad) và định dạng file.
"""

import os
import shutil
import tempfile
import pytest
from pathlib import Path

from src.assistant_tool.graphics_optimizer import Poe2GraphicsOptimizer, PROFILES

SAMPLE_INI_CONTENT = """[LOGIN]
save_login=true
gateway_id=Singapore
username=tester@example.com
account_name=HERO#1234
[DISPLAY]
resolution_width=2560
resolution_height=1440
renderer_type=DirectX12
fullscreen=true
maximize_window=true
borderless_windowed_fullscreen=true
shadow_type=High
vsync_mode=On
use_dynamic_particle_culling2=false
screenspace_effects=2
screenspace_effects_resolution=1
light_quality=2
texture_filtering=2
bloom_strength=0.5
framerate_limit=144
framerate_limit_enabled=true
background_framerate_limit=60
background_framerate_limit_enabled=true
water_detail=2
global_illumination_detail=2
time_manipulation_effects=true
screen_shake_v2=true
triple_buffering=true
upscale=NIS
upscale_quality=Quality
[SOUND]
master_volume2=80
mute_in_background=false
channel_count=high
reverb_enabled2=true
[UI]
always_highlight=true
always_highlight.gamepad=true
use_wasd_to_move=true
reduce_user_interface_animations=false
[GENERAL]
user_input_mode=wasd
last_selected_KBM_input_mode=wasd
"""


@pytest.fixture
def temp_ini_dir():
    with tempfile.TemporaryDirectory() as td:
        ini_path = Path(td) / "poe2_production_Config.ini"
        ini_path.write_text(SAMPLE_INI_CONTENT, encoding="utf-8")
        yield Path(td), ini_path


def test_find_config_path_override(temp_ini_dir):
    _, ini_path = temp_ini_dir
    found = Poe2GraphicsOptimizer.find_config_path(override_path=ini_path)
    assert found == ini_path


def test_get_current_settings(temp_ini_dir):
    _, ini_path = temp_ini_dir
    settings = Poe2GraphicsOptimizer.get_current_settings(config_path=ini_path)
    assert settings["LOGIN"]["username"] == "tester@example.com"
    assert settings["DISPLAY"]["resolution_width"] == "2560"
    assert settings["DISPLAY"]["renderer_type"] == "DirectX12"
    assert settings["SOUND"]["mute_in_background"] == "false"
    assert settings["UI"]["always_highlight.gamepad"] == "true"


def test_backup_and_restore(temp_ini_dir):
    _, ini_path = temp_ini_dir
    base_bak, ts_bak = Poe2GraphicsOptimizer.backup_config(config_path=ini_path)
    assert base_bak is not None and base_bak.exists()
    assert ts_bak is not None and ts_bak.exists()
    assert base_bak.read_text(encoding="utf-8") == SAMPLE_INI_CONTENT

    # Thay đổi file
    ini_path.write_text("CORRUPTED_OR_CHANGED_CONTENT", encoding="utf-8")
    assert ini_path.read_text(encoding="utf-8") == "CORRUPTED_OR_CHANGED_CONTENT"

    # Restore
    restored = Poe2GraphicsOptimizer.restore_backup(config_path=ini_path)
    assert restored is True
    assert ini_path.read_text(encoding="utf-8") == SAMPLE_INI_CONTENT


def test_apply_profile_ultra_low(temp_ini_dir):
    _, ini_path = temp_ini_dir
    changes = Poe2GraphicsOptimizer.apply_profile("ultra_low", config_path=ini_path, create_backup=True)

    assert len(changes) > 0
    settings = Poe2GraphicsOptimizer.get_current_settings(config_path=ini_path)

    # 1. Kiểm tra mục DISPLAY đã được hạ về Potato Mode
    disp = settings["DISPLAY"]
    assert disp["resolution_width"] == "1280"
    assert disp["resolution_height"] == "720"
    assert disp["fullscreen"] == "false"
    assert disp["borderless_windowed_fullscreen"] == "false"
    assert disp["framerate_limit"] == "30"
    assert disp["background_framerate_limit"] == "15"
    assert disp["use_dynamic_particle_culling2"] == "true"
    assert disp["screenspace_effects"] == "0"
    assert disp["bloom_strength"] == "0.0"
    assert disp["renderer_type"] == "DirectX12"  # Giữ nguyên DirectX12 không bị xóa

    # 2. Kiểm tra mục SOUND
    snd = settings["SOUND"]
    assert snd["mute_in_background"] == "true"
    assert snd["channel_count"] == "low"
    assert snd["reverb_enabled2"] == "false"

    # 3. Kiểm tra mục UI
    ui = settings["UI"]
    assert ui["reduce_user_interface_animations"] == "true"
    assert ui["always_highlight.gamepad"] == "true"  # Khóa có dấu chấm được giữ nguyên
    assert ui["use_wasd_to_move"] == "true"

    # 4. Kiểm tra mục LOGIN & GENERAL hoàn toàn nguyên vẹn
    login = settings["LOGIN"]
    assert login["username"] == "tester@example.com"
    assert login["account_name"] == "HERO#1234"
    assert settings["GENERAL"]["user_input_mode"] == "wasd"


def test_apply_profile_low_1080p(temp_ini_dir):
    _, ini_path = temp_ini_dir
    changes = Poe2GraphicsOptimizer.apply_profile("low_1080p", config_path=ini_path, create_backup=False)

    assert len(changes) > 0
    settings = Poe2GraphicsOptimizer.get_current_settings(config_path=ini_path)
    disp = settings["DISPLAY"]
    assert disp["resolution_width"] == "1920"
    assert disp["resolution_height"] == "1080"
    assert disp["framerate_limit"] == "30"
    assert disp["background_framerate_limit"] == "15"
    assert disp["bloom_strength"] == "0.0"


def test_apply_invalid_profile(temp_ini_dir):
    _, ini_path = temp_ini_dir
    with pytest.raises(ValueError, match="Profile không hợp lệ"):
        Poe2GraphicsOptimizer.apply_profile("non_existent_profile", config_path=ini_path)


def test_missing_key_insertion(temp_ini_dir):
    td, ini_path = temp_ini_dir
    # Tạo một file INI chỉ có [DISPLAY] và 1 key
    mini_ini = td / "mini.ini"
    mini_ini.write_text("[DISPLAY]\nresolution_width=1920\n[SOUND]\nmaster_volume2=50\n", encoding="utf-8")

    changes = Poe2GraphicsOptimizer.apply_profile("ultra_low", config_path=mini_ini, create_backup=False)
    settings = Poe2GraphicsOptimizer.get_current_settings(config_path=mini_ini)

    # Key mới phải được tự động chèn vào
    assert settings["DISPLAY"]["resolution_height"] == "720"
    assert settings["DISPLAY"]["framerate_limit"] == "30"
    assert settings["SOUND"]["mute_in_background"] == "true"
