import typing
import unittest

from dataclasses import dataclass

from chip.clusters import ClusterObjects
from chip.tlv import TLVReader, TLVWriter, uint
import chip.ChipUtility

'''
This file contains tests for checking if the cluster object can generate correct TLV data.

For readability, the TLV related tests are placed in test_tlv.py, and we will test the following case:
1. Generate a struct, encode it, and decode it using TLVReader
2. Generate a dict, encode it using TLVWriter, and decode it using the cluster objects

If TLVReader / TLVWriter emitted wrong TLV data, related test cases should be added to test_tlv.py.
To avoid failures caused by schema change, this file should only contain manually crafted structs.
'''


def _encode_and_then_decode_to_native(data: ClusterObjects.ClusterObject):
    tlv = data.ToTLV()
    return TLVReader(tlv).get()['Any']


def _encode_attribute_and_then_decode_to_native(data, type: ClusterObjects.ClusterAttributeDescriptor):
    return TLVReader(type.ToTLV(None, data)).get()['Any']


def _encode_from_native_and_then_decode(data, cls: typing.Union[ClusterObjects.ClusterObject, ClusterObjects.ClusterAttributeDescriptor]):
    tlv = TLVWriter()
    tlv.put(None, data)
    return cls.FromTLV(bytes(tlv.encoding))


class TestClusterObjects(unittest.TestCase):
    @dataclass
    class C(ClusterObjects.ClusterObject):
        @chip.ChipUtility.classproperty
        def descriptor(cls) -> ClusterObjects.ClusterObjectDescriptor:
            return ClusterObjects.ClusterObjectDescriptor(
                Fields=[
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="X", Tag=0, Type=uint),
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="Y", Tag=1, Type=int),
                ])
        X: 'uint' = None
        Y: 'int' = None

    def test_basic_encode(self):
        data = TestClusterObjects.C(X=5, Y=23)
        res = _encode_and_then_decode_to_native(data)
        self.assertEqual(res, {0: 5, 1: 23})

    def test_basic_decode(self):
        res = _encode_from_native_and_then_decode(
            {0: uint(5), 1: 23}, TestClusterObjects.C)
        self.assertEqual(res, TestClusterObjects.C(X=5, Y=23))

    @dataclass
    class StructWithArray(ClusterObjects.ClusterObject):
        @chip.ChipUtility.classproperty
        def descriptor(cls) -> ClusterObjects.ClusterObjectDescriptor:
            return ClusterObjects.ClusterObjectDescriptor(
                Fields=[
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="X", Tag=0, Type=typing.List[uint]),
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="Y", Tag=1, Type=int),
                ])

        X: typing.List['uint'] = None
        Y: int = None

    def test_struct_w_array_encode(self):
        data = TestClusterObjects.StructWithArray(X=[5, 6], Y=23)
        res = _encode_and_then_decode_to_native(data)
        self.assertEqual(res, {0: [5, 6], 1: 23})

    def test_struct_w_array_decode(self):
        res = _encode_from_native_and_then_decode(
            {0: [uint(5), uint(6)], 1: 23}, TestClusterObjects.StructWithArray)
        self.assertEqual(
            res, TestClusterObjects.StructWithArray(X=[5, 6], Y=23))

    @dataclass
    class StructWithEmbeddedStructAndString(ClusterObjects.ClusterObject):
        @chip.ChipUtility.classproperty
        def descriptor(cls) -> ClusterObjects.ClusterObjectDescriptor:
            return ClusterObjects.ClusterObjectDescriptor(
                Fields=[
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="X", Tag=0, Type=str),
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="Y", Tag=1, Type=TestClusterObjects.C),
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="Z", Tag=2, Type=bytes),
                ])

        X: 'str' = None
        Y: 'TestClusterObjects.C' = None
        Z: 'bytes' = None

    def test_struct_w_string_and_string_encode(self):
        data = TestClusterObjects.StructWithEmbeddedStructAndString(
            X='test-str', Y=TestClusterObjects.C(X=12, Y=34), Z=b'byte-string')
        res = _encode_and_then_decode_to_native(data)
        self.assertEqual(
            res, {0: 'test-str', 1: {0: 12, 1: 34}, 2: b'byte-string'})

    def test_struct_w_string_and_string_decode(self):
        res = _encode_from_native_and_then_decode(
            {0: 'test-str', 1: {0: uint(12), 1: 34}, 2: b'byte-string'},
            TestClusterObjects.StructWithEmbeddedStructAndString)
        self.assertEqual(
            res, TestClusterObjects.StructWithEmbeddedStructAndString(
                X='test-str', Y=TestClusterObjects.C(X=12, Y=34), Z=b'byte-string'))

    @dataclass
    class StructWithArrayOfStructWithArray(ClusterObjects.ClusterObject):
        @chip.ChipUtility.classproperty
        def descriptor(cls) -> ClusterObjects.ClusterObjectDescriptor:
            return ClusterObjects.ClusterObjectDescriptor(
                Fields=[
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="X", Tag=0, Type=typing.List[str]),
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="Y", Tag=1, Type=typing.List[TestClusterObjects.C]),
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="Z", Tag=2, Type=typing.List[TestClusterObjects.StructWithArray]),
                    # Recursive!
                    ClusterObjects.ClusterObjectFieldDescriptor(
                        Label="W", Tag=3, Type=typing.List[TestClusterObjects.StructWithArrayOfStructWithArray]),
                ])

        X: typing.List['str'] = None
        Y: typing.List['TestClusterObjects.C'] = None
        Z: typing.List['TestClusterObjects.StructWithArray'] = None
        W: typing.List['TestClusterObjects.StructWithArrayOfStructWithArray'] = None

    def test_struct_with_array_of_struct_with_array_encode(self):
        C = TestClusterObjects.C
        SWA = TestClusterObjects.StructWithArray
        SWAOSWA = TestClusterObjects.StructWithArrayOfStructWithArray
        data = TestClusterObjects.StructWithArrayOfStructWithArray(
            X=['test-str1', 'test-str2', 'test-str3'],
            Y=[C(X=12, Y=34), C(X=56, Y=78), C(X=23, Y=33)],
            Z=[SWA(X=[12, 34], Y=5678), SWA(X=[1, 3], Y=57),
               SWA(X=[2, 4], Y=68), SWA(X=[233, 333], Y=333)],
            W=[SWAOSWA(X=['test-str4'], Y=[C(X=55, Y=66)], Z=[SWA(X=[123], Y=456)], W=[])])
        res = _encode_and_then_decode_to_native(data)
        self.assertEqual(
            res,
            {0: ['test-str1', 'test-str2', 'test-str3'],
             1: [{0: 12, 1: 34}, {0: 56, 1: 78}, {0: 23, 1: 33}],
             2: [{0: [12, 34], 1: 5678},
                 {0: [1, 3], 1: 57},
                 {0: [2, 4], 1: 68},
                 {0: [233, 333], 1: 333}],
             3: [{0: ['test-str4'], 1: [{0: 55, 1: 66}], 2: [{0: [123], 1: 456}], 3: []}]})

    def test_struct_with_array_of_struct_with_array_decode(self):
        res = _encode_from_native_and_then_decode(
            {0: ['test-str1', 'test-str2', 'test-str3'],
             1: [{0: uint(12), 1: 34}, {0: uint(56), 1: 78}, {0: uint(23), 1: 33}],
             2: [{0: [uint(12), uint(34)], 1: 5678},
                 {0: [uint(1), uint(3)], 1: 57},
                 {0: [uint(2), uint(4)], 1: 68},
                 {0: [uint(233), uint(333)], 1: 333}],
             3: [{0: ['test-str4'], 1: [{0: uint(55), 1: 66}], 2: [{0: [uint(123)], 1: 456}], 3: []}]},
            TestClusterObjects.StructWithArrayOfStructWithArray)

        C = TestClusterObjects.C
        SWA = TestClusterObjects.StructWithArray
        SWAOSWA = TestClusterObjects.StructWithArrayOfStructWithArray

        data = TestClusterObjects.StructWithArrayOfStructWithArray(
            X=['test-str1', 'test-str2', 'test-str3'],
            Y=[C(X=12, Y=34), C(X=56, Y=78), C(X=23, Y=33)],
            Z=[SWA(X=[12, 34], Y=5678), SWA(X=[1, 3], Y=57),
               SWA(X=[2, 4], Y=68), SWA(X=[233, 333], Y=333)],
            W=[SWAOSWA(X=['test-str4'], Y=[C(X=55, Y=66)], Z=[SWA(X=[123], Y=456)], W=[])])

        self.assertEqual(res, data)


class TestAttributeDescriptor(unittest.TestCase):
    class IntAttribute(ClusterObjects.ClusterAttributeDescriptor):
        @chip.ChipUtility.classproperty
        def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor:
            return ClusterObjects.ClusterObjectFieldDescriptor(Type=int)

    def test_basic_encode(self):
        res = _encode_attribute_and_then_decode_to_native(
            42, TestAttributeDescriptor.IntAttribute)
        self.assertEqual(res, 42)

    def test_basic_decode(self):
        res = _encode_from_native_and_then_decode(
            42, TestAttributeDescriptor.IntAttribute)
        self.assertEqual(res, 42)

    class StructAttribute(ClusterObjects.ClusterAttributeDescriptor):
        @chip.ChipUtility.classproperty
        def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor:
            return ClusterObjects.ClusterObjectFieldDescriptor(Type=TestClusterObjects.C)

    def test_struct_encode(self):
        res = _encode_attribute_and_then_decode_to_native(
            TestClusterObjects.C(X=42, Y=24), TestAttributeDescriptor.StructAttribute)
        self.assertEqual(res, {0: 42, 1: 24})

    def test_struct_decode(self):
        res = _encode_from_native_and_then_decode(
            {0: uint(42), 1: 24}, TestClusterObjects.C)
        self.assertEqual(res, TestClusterObjects.C(X=42, Y=24))

    class ArrayAttribute(ClusterObjects.ClusterAttributeDescriptor):
        @chip.ChipUtility.classproperty
        def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor:
            return ClusterObjects.ClusterObjectFieldDescriptor(Type=typing.List[int])

    def test_array_encode(self):
        res = _encode_attribute_and_then_decode_to_native(
            [1, 2, 3, 4, 5], TestAttributeDescriptor.ArrayAttribute)
        self.assertEqual(res, [1, 2, 3, 4, 5])

    def test_array_decode(self):
        res = _encode_from_native_and_then_decode(
            [1, 2, 3, 4, 5], TestAttributeDescriptor.ArrayAttribute)
        self.assertEqual(res, [1, 2, 3, 4, 5])


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