# 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 os
import unittest
import logging
from io import StringIO
from olc.utils.env_config import EnvConfig


class TestEnvConfig(unittest.TestCase):
    def setUp(self):
        # 保存原始环境变量
        self.original_env = os.environ.copy()

    def tearDown(self):
        # 恢复原始环境变量
        os.environ.clear()
        os.environ.update(self.original_env)

    def test_get_with_default(self):
        # 测试获取不存在的环境变量,使用默认值
        result = EnvConfig.get("NON_EXISTENT_VAR", "default_value")
        self.assertEqual(result, "default_value")

        # 测试获取不存在的环境变量,默认值为 None
        result = EnvConfig.get("NON_EXISTENT_VAR")
        self.assertIsNone(result)

    def test_get_with_existing_var(self):
        # 设置环境变量
        os.environ["TEST_VAR"] = "test_value"

        # 测试获取存在的环境变量
        result = EnvConfig.get("TEST_VAR")
        self.assertEqual(result, "test_value")

    def test_get_with_cast(self):
        # 测试转换为 int
        os.environ["TEST_INT"] = "123"
        result = EnvConfig.get("TEST_INT", cast=int)
        self.assertEqual(result, 123)
        self.assertIsInstance(result, int)

        # 测试转换为 float
        os.environ["TEST_FLOAT"] = "123.45"
        result = EnvConfig.get("TEST_FLOAT", cast=float)
        self.assertEqual(result, 123.45)
        self.assertIsInstance(result, float)

        # 测试转换为 bool
        os.environ["TEST_BOOL_TRUE"] = "true"
        result = EnvConfig.get("TEST_BOOL_TRUE", cast=bool)
        self.assertTrue(result)

        os.environ["TEST_BOOL_FALSE"] = "false"
        result = EnvConfig.get("TEST_BOOL_FALSE", cast=bool)
        self.assertFalse(result)

        # 测试其他布尔值表示
        os.environ["TEST_BOOL_1"] = "1"
        result = EnvConfig.get("TEST_BOOL_1", cast=bool)
        self.assertTrue(result)

        os.environ["TEST_BOOL_YES"] = "yes"
        result = EnvConfig.get("TEST_BOOL_YES", cast=bool)
        self.assertTrue(result)

        os.environ["TEST_BOOL_ON"] = "on"
        result = EnvConfig.get("TEST_BOOL_ON", cast=bool)
        self.assertTrue(result)

    def test_get_with_invalid_cast(self):
        # 测试无效的类型转换
        os.environ["TEST_INVALID"] = "not a number"
        result = EnvConfig.get("TEST_INVALID", cast=int)
        # 注意:根据实现,当类型转换失败时,应该返回 None
        self.assertIsNone(result)

    def test_invalid_int_cast_returns_none(self):
        """测试无效int转换返回None"""
        os.environ["INVALID_INT"] = "abc"
        result = EnvConfig.get("INVALID_INT", cast=int)
        self.assertIsNone(result)

    def test_invalid_float_cast_returns_none(self):
        """测试无效float转换返回None"""
        os.environ["INVALID_FLOAT"] = "not_a_float"
        result = EnvConfig.get("INVALID_FLOAT", cast=float)
        self.assertIsNone(result)

    def test_various_invalid_values(self):
        """测试各种无效值的转换失败处理"""
        test_cases = [
            ("EMPTY_STRING", "", int),
            ("SPACES", "   ", int),
            ("SPECIAL_CHARS", "!@#$%", int),
            ("NEGATIVE_FLOAT_FOR_INT", "-3.14", int),
        ]

        for var_name, value, cast_type in test_cases:
            with self.subTest(var=var_name, value=value, cast=cast_type):
                os.environ[var_name] = value
                result = EnvConfig.get(var_name, default="fallback", cast=cast_type)
                # 转换失败应该返回 None(忽略默认值)
                self.assertIsNone(result,
                                 f"{var_name}={value!r} 转换为 {cast_type.__name__} 应该返回 None")

    def test_bool_edge_cases(self):
        """测试布尔值转换的边界情况"""
        bool_test_cases = [
            ("TRUE_UPPER", "True", True),
            ("FALSE_UPPER", "False", False),
            ("ZERO", "0", False),
            ("NO", "no", False),
            ("OFF", "off", False),
            ("RANDOM", "random_string", False),  # 不在认可列表中
        ]

        for var_name, value, expected in bool_test_cases:
            with self.subTest(var=var_name, value=value):
                os.environ[var_name] = value
                result = EnvConfig.get(var_name, cast=bool)
                self.assertEqual(result, expected,
                               f"{var_name}={value!r} 应该转换为 {expected}")

    def test_none_value_handling(self):
        """测试环境变量值为空字符串的情况"""
        os.environ["EMPTY_VAR"] = ""
        
        # 不带 cast 应该返回空字符串
        result = EnvConfig.get("EMPTY_VAR")
        self.assertEqual(result, "")
        
        # 带 int cast 应该失败(空字符串不能转int)
        result = EnvConfig.get("EMPTY_VAR", cast=int)
        self.assertIsNone(result)


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