# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

from __future__ import absolute_import, division, print_function

import sys
import types
import warnings

import pytest

from cryptography.utils import deprecated


class TestDeprecated(object):
    def test_deprecated(self, monkeypatch):
        mod = types.ModuleType("TestDeprecated/test_deprecated")
        monkeypatch.setitem(sys.modules, mod.__name__, mod)
        mod.X = deprecated(
            value=1,
            module_name=mod.__name__,
            message="deprecated message text",
            warning_class=DeprecationWarning,
        )
        mod.Y = deprecated(
            value=2,
            module_name=mod.__name__,
            message="more deprecated text",
            warning_class=PendingDeprecationWarning,
        )
        mod = sys.modules[mod.__name__]
        mod.Z = 3

        with warnings.catch_warnings(record=True) as log:
            warnings.simplefilter("always", PendingDeprecationWarning)
            warnings.simplefilter("always", DeprecationWarning)
            assert mod.X == 1
            assert mod.Y == 2
            assert mod.Z == 3

        [msg1, msg2] = log
        assert msg1.category is DeprecationWarning
        assert msg1.message.args == ("deprecated message text",)

        assert msg2.category is PendingDeprecationWarning
        assert msg2.message.args == ("more deprecated text",)

        assert "Y" in dir(mod)

    def test_deleting_deprecated_members(self, monkeypatch):
        mod = types.ModuleType("TestDeprecated/test_deprecated")
        monkeypatch.setitem(sys.modules, mod.__name__, mod)
        mod.X = deprecated(
            value=1,
            module_name=mod.__name__,
            message="deprecated message text",
            warning_class=DeprecationWarning,
        )
        mod.Y = deprecated(
            value=2,
            module_name=mod.__name__,
            message="more deprecated text",
            warning_class=PendingDeprecationWarning,
        )
        mod = sys.modules[mod.__name__]
        mod.Z = 3

        with warnings.catch_warnings(record=True) as log:
            warnings.simplefilter("always", PendingDeprecationWarning)
            warnings.simplefilter("always", DeprecationWarning)
            del mod.X
            del mod.Y
            del mod.Z

        [msg1, msg2] = log
        assert msg1.category is DeprecationWarning
        assert msg1.message.args == ("deprecated message text",)

        assert msg2.category is PendingDeprecationWarning
        assert msg2.message.args == ("more deprecated text",)

        assert "X" not in dir(mod)
        assert "Y" not in dir(mod)
        assert "Z" not in dir(mod)

        with pytest.raises(AttributeError):
            del mod.X
