import os
import unittest
from unittest import mock

from xsdk.http_proxy import ProxyConfig
from xsdk.mail_client import MailAccountData
from xsdk.redis_client import RedisClient
from xsdk.xutil import Xutil


class EnvNamesTestCase(unittest.TestCase):
    def tearDown(self) -> None:
        RedisClient._client = None

    def test_get_env_param_returns_default_when_key_missing(self) -> None:
        with mock.patch.dict(os.environ, {}, clear=True):
            result = Xutil.get_env_param("NEW_ENV", default="default-value")

        self.assertEqual(result, "default-value")

    def test_mail_account_uses_new_env_name(self) -> None:
        with mock.patch.dict(
            os.environ,
            {"XENV_MAIL_ACCT": "123456@new_pwd"},
            clear=True,
        ):
            with mock.patch("xsdk.mail_client.random.randint", return_value=0):
                account = MailAccountData.get_default_account()

        self.assertEqual(account.user, "123456@qq.com")
        self.assertEqual(account.password, "new_pwd")

    def test_mail_account_returns_empty_when_env_missing(self) -> None:
        with mock.patch.dict(os.environ, {}, clear=True):
            with mock.patch("xsdk.mail_client.random.randint", return_value=0):
                account = MailAccountData.get_default_account()

        self.assertEqual(account.user, "")
        self.assertEqual(account.password, "")

    def test_proxy_config_uses_new_env_name(self) -> None:
        with mock.patch.dict(
            os.environ,
            {"XENV_HTTP_PROXY": "http://new_user:new_pwd@new_host:8080"},
            clear=True,
        ):
            proxy_list = ProxyConfig.get_config_list()

        self.assertEqual(len(proxy_list), 1)
        self.assertEqual(proxy_list[0].host, "new_host")
        self.assertEqual(proxy_list[0].port, 8080)

    def test_proxy_config_returns_empty_when_env_missing(self) -> None:
        with mock.patch.dict(os.environ, {}, clear=True):
            proxy_list = ProxyConfig.get_config_list()

        self.assertEqual(proxy_list, [])

    def test_redis_client_uses_new_env_name(self) -> None:
        RedisClient._client = None
        sentinel = object()
        with mock.patch.dict(
            os.environ,
            {"XENV_REDIS": "redis://new-host:6379/1"},
            clear=True,
        ):
            with mock.patch("xsdk.redis_client.redis.Redis.from_url", return_value=sentinel) as mock_from_url:
                client = RedisClient.get_client()

        self.assertIs(client, sentinel)
        mock_from_url.assert_called_once_with("redis://new-host:6379/1", decode_responses=True)

    def test_redis_client_returns_none_when_env_missing(self) -> None:
        RedisClient._client = None
        with mock.patch.dict(os.environ, {}, clear=True):
            with mock.patch("xsdk.redis_client.redis.Redis.from_url") as mock_from_url:
                client = RedisClient.get_client()

        self.assertIsNone(client)
        mock_from_url.assert_not_called()


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