# Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
# OpenOLC 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 olc.bean.olc_config_rule import (
    OlcMultiTag,
    Group,
    FlowPolicy,
    AdmissionPolicy,
    OlcRule,
    OlcConfigRule,
    AlgInstance,
    FlowControlMode,
    PolicyType,
    AssignAlgName
)


class TestOlcConfigRule(unittest.TestCase):
    def test_olc_multi_tag_from_dict(self):
        """测试OlcMultiTag.from_dict方法"""
        data = {
            "tag": "service",
            "match": "equal",
            "values": ["service1", "service2"]
        }
        tag = OlcMultiTag.from_dict(data)
        self.assertEqual(tag.tag, "service")
        self.assertEqual(tag.match, "equal")
        self.assertEqual(tag.values, ["service1", "service2"])

        # 测试None输入
        self.assertIsNone(OlcMultiTag.from_dict(None))

    def test_group_from_dict(self):
        """测试Group.from_dict方法"""
        data = {
            "priority": 1,
            "enabled": True,
            "name": "test_group",
            "type": "normal",
            "tags": [
                {"tag": "service", "match": "equal", "values": ["service1"]}
            ]
        }
        group = Group.from_dict(data)
        self.assertEqual(group.priority, 1)
        self.assertEqual(group.enabled, True)
        self.assertEqual(group.name, "test_group")
        self.assertEqual(group.type, "normal")
        self.assertEqual(len(group.tags), 1)

        # 测试None输入
        self.assertIsNone(Group.from_dict(None))

    def test_alg_instance_from_dict(self):
        """测试AlgInstance.from_dict方法"""
        data = {
            "algName": "test_alg",
            "algParam": {"param1": "value1", "param2": "value2"}
        }
        alg = AlgInstance.from_dict(data)
        self.assertEqual(alg.alg_name, "test_alg")
        self.assertEqual(alg.alg_param, {"param1": "value1", "param2": "value2"})

        # 测试空参数
        data_no_params = {"algName": "test_alg"}
        alg_no_params = AlgInstance.from_dict(data_no_params)
        self.assertEqual(alg_no_params.alg_name, "test_alg")
        self.assertEqual(alg_no_params.alg_param, {})

        # 测试None输入
        self.assertIsNone(AlgInstance.from_dict(None))

        # 测试空算法名
        data_empty_name = {"algName": "", "algParams": {}}
        self.assertIsNone(AlgInstance.from_dict(data_empty_name))

    def test_alg_instance_methods(self):
        """测试AlgInstance的方法"""
        alg = AlgInstance(
            alg_name="test_alg",
            alg_param={"safeMode": 1, "safeRateLimit": 100}
        )
        self.assertEqual(alg.get_safe_mode(), 1)
        self.assertEqual(alg.get_safe_rate_limit(), 100)

        # 测试默认值
        alg_no_params = AlgInstance(alg_name="test_alg", alg_param=None)
        self.assertEqual(alg_no_params.get_safe_mode(), -1)
        self.assertIsNone(alg_no_params.get_safe_rate_limit())

    def test_flow_policy_from_dict(self):
        """测试FlowPolicy.from_dict方法"""
        data = {
            "name": "test_flow",
            "enabled": True,
            "category": "test_category",
            "blockMsg": "test_block_msg",
            "policyType": "NODE",
            "timeUnit": "SECOND",
            "timeInterval": 1,
            "rateLimit": 100,
            "burstLimit": 200,
            "maxWaitTimeMs": 500,
            "flowControlMode": "qps",
            "calculateAlg": {"algName": "calc_alg"},
            "assignAlg": {"algName": "assign_alg"}
        }
        policy = FlowPolicy.from_dict(data)
        self.assertEqual(policy.name, "test_flow")
        self.assertEqual(policy.enabled, True)
        self.assertEqual(policy.category, "test_category")
        self.assertEqual(policy.block_msg, "test_block_msg")
        self.assertEqual(policy.policy_type, "NODE")
        self.assertEqual(policy.time_unit, "second")
        self.assertEqual(policy.time_interval, 1)
        self.assertEqual(policy.rate_limit, 100)
        self.assertEqual(policy.burst_limit, 200)
        self.assertEqual(policy.max_wait_time_ms, 500)
        self.assertEqual(policy.flow_control_mode, "qps")
        self.assertIsNotNone(policy.calculate_alg)
        self.assertIsNotNone(policy.assign_alg)

        # 测试None输入
        self.assertIsNone(FlowPolicy.from_dict(None))

    def test_flow_policy_methods(self):
        """测试FlowPolicy的方法"""
        policy = FlowPolicy(
            name="test_flow",
            category="test_category",
            enabled=True,
            block_msg="test_block_msg",
            policy_type="NODE",
            time_unit="second",
            time_interval=1,
            rate_limit=100,
            burst_limit=200,
            flow_control_mode="qps",
            max_wait_time_ms=500,
            calculate_alg=None,
            assign_alg=None
        )

        # 测试time_unit_to_seconds方法
        self.assertEqual(policy.time_unit_to_seconds(), 1)

        # 测试set_default_value方法
        policy.set_default_value("test_group")
        self.assertEqual(policy.name, "test_flow")  # 名称已设置,不应改变

        # 测试check方法
        self.assertTrue(policy.check())

    def test_admission_policy_from_dict(self):
        """测试AdmissionPolicy.from_dict方法"""
        data = {
            "name": "test_admission",
            "enabled": True,
            "category": "test_category",
            "blockMsg": "test_block_msg",
            "type": "test_type",
            "calculateAlg": {"algName": "calc_alg"}
        }
        policy = AdmissionPolicy.from_dict(data)
        self.assertEqual(policy.name, "test_admission")
        self.assertEqual(policy.enabled, True)
        self.assertEqual(policy.category, "test_category")
        self.assertEqual(policy.block_msg, "test_block_msg")
        self.assertEqual(policy.type, "test_type")
        self.assertIsNotNone(policy.calculate_alg)

        # 测试None输入
        self.assertIsNone(AdmissionPolicy.from_dict(None))

    def test_admission_policy_methods(self):
        """测试AdmissionPolicy的方法"""
        policy = AdmissionPolicy(
            name="test_admission",
            category="test_category",
            enabled=True,
            block_msg="test_block_msg",
            type="test_type",
            calculate_alg=None
        )

        # 测试set_default_value方法
        policy.set_default_value("test_group")
        self.assertEqual(policy.name, "test_admission")  # 名称已设置,不应改变

        # 测试check方法
        self.assertTrue(policy.check())

    def test_olc_rule_from_dict(self):
        """测试OlcRule.from_dict方法"""
        data = {
            "group": {
                "priority": 1,
                "enabled": True,
                "name": "test_group",
                "type": "normal",
                "tags": [
                    {"tag": "service", "match": "equal", "values": ["service1"]}
                ]
            },
            "flow": {
                "name": "test_flow",
                "enabled": True,
                "category": "test_category",
                "blockMsg": "test_block_msg",
                "policyType": "NODE",
                "timeUnit": "second",
                "timeInterval": 1,
                "rateLimit": 100,
                "burstLimit": 200,
                "maxWaitTimeMs": 500,
                "flowControlMode": "qps"
            },
            "admission": {
                "name": "test_admission",
                "enabled": True,
                "category": "test_category",
                "blockMsg": "test_block_msg",
                "type": "test_type"
            }
        }
        rule = OlcRule.from_dict(data)
        self.assertIsNotNone(rule.group)
        self.assertIsNotNone(rule.flow)
        self.assertIsNotNone(rule.admission)

        # 测试get_all_policy方法
        policies = rule.get_all_policy()
        self.assertEqual(len(policies), 2)

        # 测试None输入
        self.assertIsNone(OlcRule.from_dict(None))

    def test_olc_config_rule_from_dict(self):
        """测试OlcConfigRule.from_dict方法"""
        data = {
            "domain": "test_domain",
            "rules": [
                {
                    "group": {
                        "priority": 1,
                        "enabled": True,
                        "name": "test_group",
                        "type": "normal",
                        "tags": [
                            {"tag": "service", "match": "equal", "values": ["service1"]}
                        ]
                    },
                    "flow": {
                        "name": "test_flow",
                        "enabled": True,
                        "category": "test_category",
                        "blockMsg": "test_block_msg",
                        "policyType": "NODE",
                        "timeUnit": "second",
                        "timeInterval": 1,
                        "rateLimit": 100,
                        "burstLimit": 200,
                        "maxWaitTimeMs": 500,
                        "flowControlMode": "qps"
                    }
                }
            ]
        }
        config_rule = OlcConfigRule.from_dict(data)
        self.assertEqual(config_rule.domain, "test_domain")
        self.assertEqual(len(config_rule.rules), 1)

    def test_olc_config_rule_valid(self):
        """测试OlcConfigRule.valid方法"""
        # 测试无效域名
        config_rule_invalid = OlcConfigRule(
            domain="",
            rules=[]
        )
        self.assertFalse(config_rule_invalid.valid())


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