# coding: utf-8
# Copyright (c) 2026 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

import unittest
from unittest.mock import Mock, MagicMock


class MockConanFile:
    """模拟ConanFile类，用于测试check_luajit_support_deterministic方法"""
    
    def __init__(self):
        self.conf = Mock()
    
    def check_luajit_support_deterministic(self):
        """检查luajit版本是否支持-d选项
        
        从 self.conf.get("user.tools:luajit") 获取版本信息
        格式示例: luajit/2.1.0.b015@openubmc/stable
        
        规则: 只有版本号为 2.1.0.b015、2.1.0.b016、2.1.0.b017 时不支持-d选项
        其他版本都支持-d选项
        """
        try:
            import re
            # 获取luajit版本信息
            luajit_ref = self.conf.get("user.tools:luajit", default=None)
            if not luajit_ref:
                # 如果无法获取版本信息，默认使用-d选项
                return True
            
            # 从 luajit/2.1.0.b015@openubmc/stable 格式中提取版本号
            # 匹配版本号部分: 数字.数字.数字.b数字（忽略大小写）
            match = re.search(r'luajit/(\d+\.\d+\.\d+\.b\d+)', luajit_ref, re.IGNORECASE)
            if match:
                version = match.group(1).lower()  # 转换为小写后比较
                # 只有这三个特定版本不支持-d选项
                if version in ['2.1.0.b015', '2.1.0.b016', '2.1.0.b017']:
                    return False
            
            # 其他所有情况都支持-d选项
            return True
        except Exception:
            # 如果出现异常，默认使用-d选项
            return True


class TestLuajitVersionCheck(unittest.TestCase):
    """测试luajit版本检查功能"""
    
    def setUp(self):
        self.conan_file = MockConanFile()
    
    def test_version_2_1_0_b015_should_not_support(self):
        """测试版本2.1.0.b015不应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b015@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertFalse(result)
    
    def test_version_2_1_0_b016_should_not_support(self):
        """测试版本2.1.0.b016不应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b016@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertFalse(result)
    
    def test_version_2_1_0_b017_should_not_support(self):
        """测试版本2.1.0.b017不应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b017@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertFalse(result)
    
    def test_version_2_1_0_b014_should_support(self):
        """测试版本2.1.0.b014应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b014@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_version_2_1_0_b018_should_support(self):
        """测试版本2.1.0.b018应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b018@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_version_2_1_0_b019_should_support(self):
        """测试版本2.1.0.b019应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b019@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_version_2_1_0_b100_should_support(self):
        """测试版本2.1.0.b100应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b100@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_version_2_1_1_b001_should_support(self):
        """测试版本2.1.1.b001应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.1.b001@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_version_2_2_0_b001_should_support(self):
        """测试版本2.2.0.b001应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.2.0.b001@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_version_3_0_0_b001_should_support(self):
        """测试版本3.0.0.b001应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/3.0.0.b001@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_different_channel_b015_should_not_support(self):
        """测试不同channel的2.1.0.b015版本不应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b015@mycompany/testing"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertFalse(result)
    
    def test_no_channel_b016_should_not_support(self):
        """测试无channel的2.1.0.b016版本不应该支持-d选项"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b016"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertFalse(result)
    
    def test_conf_returns_none(self):
        """测试conf.get返回None时应该使用-d选项"""
        self.conan_file.conf.get.return_value = None
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_conf_returns_empty_string(self):
        """测试conf.get返回空字符串时应该使用-d选项"""
        self.conan_file.conf.get.return_value = ""
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_invalid_format(self):
        """测试无效格式应该使用-d选项"""
        self.conan_file.conf.get.return_value = "some_invalid_format"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_conf_raises_exception(self):
        """测试conf.get抛出异常时应该使用-d选项"""
        self.conan_file.conf.get.side_effect = Exception("Config error")
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertTrue(result)
    
    def test_version_with_extra_parts(self):
        """测试版本字符串包含额外部分"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.b015@openubmc/stable#revision123"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertFalse(result)
    
    def test_version_case_insensitive_b015(self):
        """测试版本号大小写不敏感：LuaJIT/2.1.0.B015 也应该被识别为黑名单"""
        self.conan_file.conf.get.return_value = "LuaJIT/2.1.0.B015@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        # B015会被转换为小写b015，匹配黑名单，不支持-d
        self.assertFalse(result)
    
    def test_version_case_insensitive_b016_upper(self):
        """测试版本号大小写不敏感：2.1.0.B016 也应该被识别为黑名单"""
        self.conan_file.conf.get.return_value = "luajit/2.1.0.B016@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertFalse(result)
    
    def test_version_case_insensitive_mixed(self):
        """测试版本号大小写不敏感：混合大小写 2.1.0.b017"""
        self.conan_file.conf.get.return_value = "LUAJIT/2.1.0.b017@openubmc/stable"
        result = self.conan_file.check_luajit_support_deterministic()
        self.assertFalse(result)


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