"""AutoPOE2 - Unit Tests for StashMemoryReader (Doc 63 / SSoT 2026).

Kiểm thử bộ nhớ đệm RAM và khả năng đồng bộ Hybrid của Stash & Inventory:
- Khởi tạo bộ nhớ đệm 60 ô túi đồ.
- Cập nhật và truy xuất trạng thái ô đồ O(1).
- Đồng bộ hai chiều với ma trận quang học (Optical Matrix).
- Kiểm tra cơ chế an toàn Fail-Soft khi không thể kết nối PID.
"""

from unittest.mock import MagicMock, patch
import pytest

from src.assistant_tool.stash.stash_memory_reader import (
    StashMemoryReader,
    SlotMemoryData,
)


def test_stash_memory_reader_cache_init():
    """Kiểm tra khởi tạo 60 ô túi đồ mặc định trong RAM Cache."""
    reader = StashMemoryReader()
    assert len(reader._cache) == 60

    # Tất cả 60 ô ban đầu đều rỗng
    assert len(reader.get_all_occupied_slots()) == 0
    assert reader.get_waystones_count() == 0

    # Kiểm tra ô góc
    slot_0_0 = reader.get_slot_data(0, 0)
    assert slot_0_0.col == 0
    assert slot_0_0.row == 0
    assert not slot_0_0.is_occupied


def test_stash_memory_reader_update_slot():
    """Kiểm tra cập nhật và truy xuất dữ liệu vật phẩm trong RAM Cache."""
    reader = StashMemoryReader()

    # Cập nhật ô [0, 0] là Waystone Tier 16
    slot_ws = reader.update_slot(
        col=0,
        row=0,
        is_occupied=True,
        item_name="Waystone (Tier 16)",
        category="WAYSTONE",
        tier=16,
    )
    assert slot_ws.is_occupied is True
    assert slot_ws.item_name == "Waystone (Tier 16)"
    assert slot_ws.tier == 16

    # Cập nhật ô [1, 0] là Chaos Orb
    reader.update_slot(
        col=1,
        row=0,
        is_occupied=True,
        item_name="Chaos Orb",
        category="CURRENCY",
    )

    # Kiểm tra số lượng
    occupied = reader.get_all_occupied_slots()
    assert len(occupied) == 2
    assert reader.get_waystones_count() == 1

    ws_slots = reader.get_waystone_slots()
    assert len(ws_slots) == 1
    assert ws_slots[0].col == 0 and ws_slots[0].row == 0


def test_stash_memory_reader_sync_with_optical():
    """Kiểm tra đồng bộ hai chiều với kết quả quét quang học."""
    reader = StashMemoryReader()

    # Giả lập ô [0, 0] đang có đồ
    reader.update_slot(col=0, row=0, is_occupied=True, item_name="Waystone")

    # Giả lập kết quả quét quang học: ô [0, 0] đã bị cất đi (is_occupied=False), ô [2, 0] có đồ mới
    mock_slot_0 = MagicMock(col=0, row=0, is_occupied=False)
    mock_slot_2 = MagicMock(col=2, row=0, is_occupied=True)

    reader.sync_with_optical_matrix([mock_slot_0, mock_slot_2])

    # Ô [0, 0] phải được cập nhật thành rỗng
    assert reader.get_slot_data(0, 0).is_occupied is False

    # Ô [2, 0] phải được đánh dấu là có đồ
    assert reader.get_slot_data(2, 0).is_occupied is True


def test_stash_memory_reader_fail_soft():
    """Kiểm tra cơ chế an toàn Fail-Soft khi không thể mở tiến trình."""
    reader = StashMemoryReader(pid=999999)  # PID không tồn tại
    assert not reader.is_attached()

    # Đọc bộ nhớ an toàn trả về None mà không gây crash
    val = reader.read_memory(0x140000000, 8)
    assert val is None

    val_u32 = reader.read_u32(0x140000000)
    assert val_u32 is None
