import os
import sys
import unittest
from unittest import mock

# 添加项目根目录到Python路径
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from src.data_provider import DataLoader, DataQueryAPI


class TestDataLoader(unittest.TestCase):
    """测试DataLoader类"""
    
    @mock.patch('requests.get')
    def test_load_data_from_online(self, mock_get):
        """测试从网络加载数据"""
        # 模拟requests.get返回值
        mock_response = mock.Mock()
        mock_response.json.return_value = {
            "version": "15.7",
            "data": [{"id": "test"}]
        }
        mock_response.raise_for_status.return_value = None
        mock_get.return_value = mock_response
        
        # 创建临时数据目录
        os.makedirs('data', exist_ok=True)
        
        # 执行测试
        loader = DataLoader(use_local_if_exists=False)
        result = loader.load_data('chess')
        
        # 验证结果
        self.assertTrue(result)
        self.assertEqual(loader.get_data('chess')['version'], '15.7')
        self.assertEqual(len(loader.get_data('chess')['data']), 1)
        
        # 清理
        if os.path.exists('data/chess.json'):
            os.remove('data/chess.json')
    
    def test_get_latest_version(self):
        """测试获取数据版本"""
        loader = DataLoader()
        
        # 模拟缓存数据
        loader.data_cache = {
            'chess': {"version": "15.7", "data": []},
            'job': {"version": "15.7", "data": []},
            'race': {"version": "15.7", "data": []}
        }
        
        # 执行测试
        version = loader.get_latest_version()
        
        # 验证结果
        self.assertEqual(version, '15.7')


class TestDataQueryAPI(unittest.TestCase):
    """测试DataQueryAPI类"""
    
    def setUp(self):
        """测试前准备"""
        # 创建模拟的DataLoader
        self.mock_loader = mock.Mock()
        self.mock_loader.load_all_data.return_value = True
        
        # 模拟加载的数据
        self.job_data = {
            "version": "15.7",
            "data": [
                {
                    "jobId": "10157",
                    "name": "重装战士",
                    "level": {
                        "2": "16%最大生命值",
                        "4": "32%最大生命值",
                    }
                }
            ]
        }
        
        self.race_data = {
            "version": "15.7",
            "data": [
                {
                    "raceId": "10154",
                    "name": "街头恶魔",
                    "level": {
                        "3": "+6% 生命值",
                        "5": "+10% 生命值",
                    }
                }
            ]
        }
        
        self.chess_data = {
            "version": "15.7",
            "data": [
                {
                    "chessId": "10275",
                    "displayName": "布兰德",
                    "raceIds": "10154",
                    "jobIds": "10172",
                    "price": "4"
                },
                {
                    "chessId": "10276",
                    "displayName": "阿利斯塔",
                    "raceIds": "",
                    "jobIds": "10157",
                    "price": "3"
                }
            ]
        }
        
        # 设置模拟数据返回
        self.mock_loader.get_data.side_effect = lambda data_type: {
            'job': self.job_data,
            'race': self.race_data,
            'chess': self.chess_data
        }.get(data_type)
    
    def test_get_chess_by_job(self):
        """测试根据职业获取棋子"""
        # 创建API实例
        api = DataQueryAPI(data_loader=self.mock_loader)
        
        # 手动设置缓存和映射(模拟_init_data方法)
        api._job_cache = {"10157": self.job_data["data"][0]}
        api._chess_cache = {
            "10275": self.chess_data["data"][0],
            "10276": self.chess_data["data"][1]
        }
        api._job_chess_map = {"10157": ["10276"]}
        
        # 执行测试
        chess_list = api.get_chess_by_job("10157")
        
        # 验证结果
        self.assertEqual(len(chess_list), 1)
        self.assertEqual(chess_list[0]["displayName"], "阿利斯塔")
    
    def test_get_chess_by_race(self):
        """测试根据特质获取棋子"""
        # 创建API实例
        api = DataQueryAPI(data_loader=self.mock_loader)
        
        # 手动设置缓存和映射
        api._race_cache = {"10154": self.race_data["data"][0]}
        api._chess_cache = {
            "10275": self.chess_data["data"][0],
            "10276": self.chess_data["data"][1]
        }
        api._race_chess_map = {"10154": ["10275"]}
        
        # 执行测试
        chess_list = api.get_chess_by_race("10154")
        
        # 验证结果
        self.assertEqual(len(chess_list), 1)
        self.assertEqual(chess_list[0]["displayName"], "布兰德")
    
    def test_get_synergy_levels(self):
        """测试获取羁绊等级信息"""
        # 创建API实例
        api = DataQueryAPI(data_loader=self.mock_loader)
        
        # 手动设置缓存
        api._job_cache = {"10157": self.job_data["data"][0]}
        api._race_cache = {"10154": self.race_data["data"][0]}
        
        # 执行测试
        job_levels = api.get_synergy_levels("10157")
        race_levels = api.get_synergy_levels("10154")
        
        # 验证结果
        self.assertEqual(len(job_levels), 2)
        self.assertEqual(job_levels["2"], "16%最大生命值")
        self.assertEqual(job_levels["4"], "32%最大生命值")
        
        self.assertEqual(len(race_levels), 2)
        self.assertEqual(race_levels["3"], "+6% 生命值")
        self.assertEqual(race_levels["5"], "+10% 生命值")


if __name__ == '__main__':
    unittest.main()