# 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_control_request import OlcControlRequest
from olc.control.context.context import OlcContext
from olc.control.context.olc_context_manager import OlcContextManager


class TestOlcContextManager(unittest.TestCase):

    def setUp(self):
        OlcContextManager.clear()

    def tearDown(self):
        OlcContextManager.clear()

    def test_get_default_is_none(self):
        result = OlcContextManager.get()
        self.assertIsNone(result)

    def test_set_and_get_context(self):
        context = OlcContext(OlcControlRequest())
        OlcContextManager.set(context)
        
        result = OlcContextManager.get()
        self.assertIsNotNone(result)
        self.assertIs(result, context)

    def test_set_none_raises_error(self):
        with self.assertRaises(ValueError) as context:
            OlcContextManager.set(None)
        
        self.assertIn("Context cannot be None", str(context.exception))

    def test_clear_resets_to_none(self):
        context = OlcContext(OlcControlRequest())
        OlcContextManager.set(context)
        
        self.assertIsNotNone(OlcContextManager.get())
        
        OlcContextManager.clear()
        self.assertIsNone(OlcContextManager.get())

    def test_context_manager_basic(self):
        context = OlcContext(OlcControlRequest())
        
        self.assertIsNone(OlcContextManager.get())
        
        with OlcContextManager.context(context):
            result = OlcContextManager.get()
            self.assertIsNotNone(result)
            self.assertIs(result, context)
        
        self.assertIsNone(OlcContextManager.get())

    def test_context_manager_yields_correct_context(self):
        context = OlcContext(OlcControlRequest())
        
        with OlcContextManager.context(context) as yielded_context:
            self.assertIs(yielded_context, context)

    def test_nested_context_manager(self):
        outer_context = OlcContext(OlcControlRequest())
        inner_context = OlcContext(OlcControlRequest())
        
        with OlcContextManager.context(outer_context):
            self.assertIs(OlcContextManager.get(), outer_context)
            
            with OlcContextManager.context(inner_context):
                self.assertIs(OlcContextManager.get(), inner_context)
            
            self.assertIs(OlcContextManager.get(), outer_context)
        
        self.assertIsNone(OlcContextManager.get())

    def test_set_overwrites_existing(self):
        context1 = OlcContext(OlcControlRequest())
        context2 = OlcContext(OlcControlRequest())
        
        OlcContextManager.set(context1)
        self.assertIs(OlcContextManager.get(), context1)
        
        OlcContextManager.set(context2)
        self.assertIs(OlcContextManager.get(), context2)

    def test_clear_when_already_none(self):
        self.assertIsNone(OlcContextManager.get())
        OlcContextManager.clear()
        self.assertIsNone(OlcContextManager.get())

    def test_context_manager_with_exception(self):
        context = OlcContext(OlcControlRequest())
        
        try:
            with OlcContextManager.context(context):
                self.assertIsNotNone(OlcContextManager.get())
                raise ValueError("test exception")
        except ValueError:
            pass
        
        self.assertIsNone(OlcContextManager.get())


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