#!/usr/bin/env python
#
#  Copyright (c) 2016, The OpenThread Authors.
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#  3. Neither the name of the copyright holder nor the
#     names of its contributors may be used to endorse or promote products
#     derived from this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#  POSSIBILITY OF SUCH DAMAGE.
#

import io
import math
import random
import struct
import unittest

import common
import config
import network_data


def convert_route_to_bytearray(route):
    return struct.pack(">HB", route.border_router_16, ((route.prf & 0x03) << 6))


def convert_routes_to_bytearray(routes):
    data = bytearray()
    for route in routes:
        data += convert_route_to_bytearray(route)

    return data


def convert_has_route_to_bytearray(has_route):
    return convert_routes_to_bytearray(has_route.routes)


def convert_border_router_to_bytearray(border_router):
    data = struct.pack(">HBB", border_router.border_router_16,
                       (border_router.o & 0x01) |
                       ((border_router.r & 0x01) << 1) |
                       ((border_router.c & 0x01) << 2) |
                       ((border_router.d & 0x01) << 3) |
                       ((border_router.s & 0x01) << 4) |
                       ((border_router.p & 0x01) << 5) |
                       ((border_router.prf & 0x03) << 6),
                       ((border_router.n & 0x01) << 7))

    return data


def convert_lowpan_id_to_bytearray(lowpan_id):
    return bytearray([lowpan_id.cid | (lowpan_id.c << 4), lowpan_id.context_length])


def convert_prefix_sub_tlvs_to_bytearray(sub_tlvs):
    data = bytearray()

    for sub_tlv in sub_tlvs:
        if isinstance(sub_tlv, network_data.HasRoute):
            value = convert_has_route_to_bytearray(sub_tlv)
            _type = sub_tlv.stable | ((0 & 0x7f) << 1)

        elif isinstance(sub_tlv, network_data.BorderRouter):
            value = convert_border_router_to_bytearray(sub_tlv)
            _type = sub_tlv.stable | ((2 & 0x7f) << 1)

        elif isinstance(sub_tlv, network_data.LowpanId):
            value = convert_lowpan_id_to_bytearray(sub_tlv)
            _type = sub_tlv.stable | ((3 & 0x7f) << 1)

        else:
            raise ValueError

        data += bytearray([_type, len(value)]) + value

    return data


def convert_server_to_bytearray(server):
    return struct.pack(">H", server.server_16) + server.server_data


def convert_service_sub_tlvs_to_bytearray(sub_tlvs):
    data = bytearray()

    for sub_tlv in sub_tlvs:
        if isinstance(sub_tlv, network_data.Server):
            value = convert_server_to_bytearray(sub_tlv)
            _type = sub_tlv.stable | ((6 & 0x7f) << 1)

        else:
            raise ValueError

        data += bytearray([_type, len(value)]) + value

    return data


def convert_service_to_bytearray(service):
    return struct.pack(">BLB", ((service.t & 0x01) << 7) | ((service.id) & 0x0f),
                       service.enterprise_number,
                       service.service_data_length) + \
        service.service_data + \
        convert_service_sub_tlvs_to_bytearray(service.sub_tlvs)


def any_border_router_16():
    return random.getrandbits(16)


def any_prf():
    return random.getrandbits(2)


def any_route():
    return network_data.Route(any_border_router_16(), any_prf())


def any_routes(count=None):
    if count is None:
        count = random.randint(0, 16)

    return [any_route() for _ in range(6)]


def any_has_route():
    return network_data.HasRoute(any_routes(), any_stable())


def any_domain_id():
    return random.getrandbits(8)


def any_prefix_length():
    return random.randint(1, 16)


def any_prefix(prefix_length=None):
    if prefix_length is None:
        prefix_length = any_prefix_length()

    return bytearray([random.getrandbits(8) for _ in range(int(math.ceil(prefix_length / 8)))])


def any_p():
    return random.getrandbits(1)


def any_s():
    return random.getrandbits(1)


def any_d():
    return random.getrandbits(1)


def any_c():
    return random.getrandbits(1)


def any_r():
    return random.getrandbits(1)


def any_o():
    return random.getrandbits(1)


def any_n():
    return random.getrandbits(1)


def any_cid():
    return random.getrandbits(4)


def any_context_length():
    return random.getrandbits(8)


def any_border_router():
    return network_data.BorderRouter(any_border_router_16(), any_prf(), any_p(), any_s(), any_d(), any_c(), any_r(), any_o(), any_n(), any_stable())


def any_lowpan_id():
    return network_data.LowpanId(any_c(), any_cid(), any_context_length(), any_stable())


def any_prefix_sub_tlvs():
    creator = [
        any_has_route,
        any_border_router,
        any_lowpan_id
    ]

    sub_tlvs = []

    for _id in range(random.randint(1, 1)):
        c = random.choice(creator)
        sub_tlvs.append(c())

    return sub_tlvs


def any_t():
    return random.getrandbits(1)


def any_id():
    return random.getrandbits(4)


def any_enterprise_number():
    return random.getrandbits(32)


def any_service_data_length():
    return random.getrandbits(8)


def any_service_data(data_length=None):
    if data_length is None:
        data_length = random.randint(0, 16)

    return bytearray([random.getrandbits(8) for _ in range(data_length)])


def any_server_16():
    return random.getrandbits(16)


def any_server_data(data_length=None):
    if data_length is None:
        data_length = random.randint(0, 32)

    return bytearray([random.getrandbits(8) for _ in range(data_length)])


def any_server():
    return network_data.Server(any_server_16(), any_server_data(), any_stable())


def any_service_sub_tlvs():
    creator = [
        any_server
    ]

    sub_tlvs = []

    for _id in range(random.randint(0, 16)):
        c = random.choice(creator)
        sub_tlvs.append(c())

    return sub_tlvs


def any_stable():
    return random.getrandbits(1)


class TestRoute(unittest.TestCase):

    def test_should_return_border_router_16_value_when_border_router_16_property_is_called(self):
        # GIVEN
        border_router_16 = any_border_router_16()

        route = network_data.Route(border_router_16, any_prf())

        # WHEN
        actual_border_router_16 = route.border_router_16

        # THEN
        self.assertEqual(border_router_16, actual_border_router_16)

    def test_should_return_prf_value_when_prf_property_is_called(self):
        # GIVEN
        prf = any_prf()

        route = network_data.Route(any_border_router_16(), prf)

        # WHEN
        actual_prf = route.prf

        # THEN
        self.assertEqual(prf, actual_prf)


class TestRouteFactory(unittest.TestCase):

    def test_should_create_Route_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        border_router_16 = any_border_router_16()
        prf = any_prf()

        factory = network_data.RouteFactory()

        data = convert_route_to_bytearray(network_data.Route(border_router_16, prf))

        # WHEN
        actual_route = factory.parse(io.BytesIO(data), None)

        # THEN
        self.assertTrue(isinstance(actual_route, network_data.Route))
        self.assertEqual(border_router_16, actual_route.border_router_16)
        self.assertEqual(prf, actual_route.prf)


class TestRoutesFactory(unittest.TestCase):

    def test_should_create_Route_list_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        routes = any_routes()

        factory = network_data.RoutesFactory(network_data.RouteFactory())

        data = convert_routes_to_bytearray(routes)
        # WHEN
        actual_routes = factory.parse(io.BytesIO(data), None)

        # THEN
        self.assertTrue(isinstance(actual_routes, list))
        self.assertEqual(routes, actual_routes)


class TestHasRoute(unittest.TestCase):

    def test_should_return_routes_value_when_routes_property_is_called(self):
        # GIVEN
        routes = any_routes()

        has_route = network_data.HasRoute(routes, any_stable())

        # WHEN
        actual_routes = has_route.routes

        # THEN
        self.assertEqual(routes, actual_routes)

    def test_should_return_stable_value_when_stable_property_is_called(self):
        # GIVEN
        stable = any_stable()

        has_route = network_data.HasRoute(any_routes(), stable)

        # WHEN
        actual_stable = has_route.stable

        # THEN
        self.assertEqual(stable, actual_stable)


class TestHasRouteFactory(unittest.TestCase):

    def test_should_create_HasRoute_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        routes = any_routes()
        stable = any_stable()

        factory = network_data.HasRouteFactory(network_data.RoutesFactory(network_data.RouteFactory()))

        data = convert_routes_to_bytearray(routes)

        message_info = common.MessageInfo()
        message_info.stable = stable

        # WHEN
        actual_has_route = factory.parse(io.BytesIO(data), message_info)

        # THEN
        self.assertTrue(isinstance(actual_has_route, network_data.HasRoute))
        self.assertEqual(routes, actual_has_route.routes)
        self.assertEqual(stable, actual_has_route.stable)


class TestPrefix(unittest.TestCase):

    def test_should_return_domain_id_value_when_domain_id_property_is_called(self):
        # GIVEN
        domain_id = any_domain_id()

        prefix = network_data.Prefix(domain_id, any_prefix_length(), any_prefix(), any_prefix_sub_tlvs(), any_stable())

        # WHEN
        actual_domain_id = prefix.domain_id

        # THEN
        self.assertEqual(domain_id, actual_domain_id)

    def test_should_return_prefix_length_value_when_prefix_length_property_is_called(self):
        # GIVEN
        prefix_length = any_prefix_length()

        prefix = network_data.Prefix(any_domain_id(), prefix_length, any_prefix(), any_prefix_sub_tlvs(), any_stable())

        # WHEN
        actual_prefix_length = prefix.prefix_length

        # THEN
        self.assertEqual(prefix_length, actual_prefix_length)

    def test_should_return_prefix_value_when_prefix_property_is_called(self):
        # GIVEN
        prefix = any_prefix()

        prefix_obj = network_data.Prefix(any_domain_id(), any_prefix_length(),
                                         prefix, any_prefix_sub_tlvs(), any_stable())

        # WHEN
        actual_prefix = prefix_obj.prefix

        # THEN
        self.assertEqual(prefix, actual_prefix)

    def test_should_return_sub_tlvs_value_when_sub_tlvs_property_is_called(self):
        # GIVEN
        sub_tlvs = any_prefix_sub_tlvs()

        prefix_obj = network_data.Prefix(any_domain_id(), any_prefix_length(), any_prefix(), sub_tlvs, any_stable())

        # WHEN
        actual_sub_tlvs = prefix_obj.sub_tlvs

        # THEN
        self.assertEqual(sub_tlvs, actual_sub_tlvs)

    def test_should_return_stable_value_when_stable_property_is_called(self):
        # GIVEN
        stable = any_stable()

        prefix_obj = network_data.Prefix(any_domain_id(), any_prefix_length(),
                                         any_prefix(), any_prefix_sub_tlvs(), stable)

        # WHEN
        actual_stable = prefix_obj.stable

        # THEN
        self.assertEqual(stable, actual_stable)


class TestPrefixSubTlvsFactory(unittest.TestCase):

    def test_should_create_SubTlvs_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        sub_tlvs = any_prefix_sub_tlvs()

        factory = network_data.PrefixSubTlvsFactory(config.create_default_network_data_prefix_sub_tlvs_factories())

        data = convert_prefix_sub_tlvs_to_bytearray(sub_tlvs)

        # WHEN
        actual_sub_tlvs = factory.parse(io.BytesIO(data), common.MessageInfo())

        # THEN
        self.assertTrue(isinstance(actual_sub_tlvs, list))
        self.assertEqual(sub_tlvs, actual_sub_tlvs)


class TestPrefixFactory(unittest.TestCase):

    def test_should_create_Prefix_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        domain_id = any_domain_id()
        prefix_length = any_prefix_length()
        prefix = any_prefix(prefix_length)
        sub_tlvs = any_prefix_sub_tlvs()

        factory = network_data.PrefixFactory(config.create_default_network_data_prefix_sub_tlvs_factory())

        data = bytearray([domain_id, prefix_length]) + prefix + convert_prefix_sub_tlvs_to_bytearray(sub_tlvs)

        message_info = common.MessageInfo()

        # WHEN
        actual_prefix = factory.parse(io.BytesIO(data), message_info)

        # THEN
        self.assertTrue(isinstance(actual_prefix, network_data.Prefix))
        self.assertEqual(domain_id, actual_prefix.domain_id)
        self.assertEqual(prefix_length, actual_prefix.prefix_length)
        self.assertEqual(prefix, actual_prefix.prefix)
        self.assertEqual(sub_tlvs, actual_prefix.sub_tlvs)


class TestBorderRouter(unittest.TestCase):

    def test_should_return_border_router_16_value_when_border_router_16_property_is_called(self):
        # GIVEN
        border_router_16 = any_border_router_16()

        border_router = network_data.BorderRouter(border_router_16, any_prf(
        ), any_p(), any_s(), any_d(), any_c(), any_r(), any_o(), any_n(), any_stable())

        # WHEN
        actual_border_router_16 = border_router.border_router_16

        # THEN
        self.assertEqual(border_router_16, actual_border_router_16)

    def test_should_return_prf_value_when_prf_property_is_called(self):
        # GIVEN
        prf = any_prf()

        border_router = network_data.BorderRouter(any_border_router_16(
        ), prf, any_p(), any_s(), any_d(), any_c(), any_r(), any_o(), any_n(), any_stable())

        # WHEN
        actual_prf = border_router.prf

        # THEN
        self.assertEqual(prf, actual_prf)

    def test_should_return_p_value_when_p_property_is_called(self):
        # GIVEN
        p = any_p()

        border_router = network_data.BorderRouter(any_border_router_16(), any_prf(
        ), p, any_s(), any_d(), any_c(), any_r(), any_o(), any_n(), any_stable())

        # WHEN
        actual_p = border_router.p

        # THEN
        self.assertEqual(p, actual_p)

    def test_should_return_s_value_when_s_property_is_called(self):
        # GIVEN
        s = any_s()

        border_router = network_data.BorderRouter(any_border_router_16(), any_prf(
        ), any_p(), s, any_d(), any_c(), any_r(), any_o(), any_n(), any_stable())

        # WHEN
        actual_s = border_router.s

        # THEN
        self.assertEqual(s, actual_s)

    def test_should_return_d_value_when_d_property_is_called(self):
        # GIVEN
        d = any_d()

        border_router = network_data.BorderRouter(any_border_router_16(), any_prf(
        ), any_p(), any_s(), d, any_c(), any_r(), any_o(), any_n(), any_stable())

        # WHEN
        actual_d = border_router.d

        # THEN
        self.assertEqual(d, actual_d)

    def test_should_return_c_value_when_c_property_is_called(self):
        # GIVEN
        c = any_c()

        border_router = network_data.BorderRouter(any_border_router_16(), any_prf(
        ), any_p(), any_s(), any_d(), c, any_r(), any_o(), any_n(), any_stable())

        # WHEN
        actual_c = border_router.c

        # THEN
        self.assertEqual(c, actual_c)

    def test_should_return_r_value_when_r_property_is_called(self):
        # GIVEN
        r = any_r()

        border_router = network_data.BorderRouter(any_border_router_16(), any_prf(
        ), any_p(), any_s(), any_d(), any_c(), r, any_o(), any_n(), any_stable())

        # WHEN
        actual_r = border_router.r

        # THEN
        self.assertEqual(r, actual_r)

    def test_should_return_o_value_when_o_property_is_called(self):
        # GIVEN
        o = any_o()

        border_router = network_data.BorderRouter(any_border_router_16(), any_prf(
        ), any_p(), any_s(), any_d(), any_c(), any_r(), o, any_n(), any_stable())

        # WHEN
        actual_o = border_router.o

        # THEN
        self.assertEqual(o, actual_o)

    def test_should_return_n_value_when_n_property_is_called(self):
        # GIVEN
        n = any_n()

        border_router = network_data.BorderRouter(any_border_router_16(), any_prf(
        ), any_p(), any_s(), any_d(), any_c(), any_r(), any_o(), n, any_stable())

        # WHEN
        actual_n = border_router.n

        # THEN
        self.assertEqual(n, actual_n)

    def test_should_return_stable_value_when_stable_property_is_called(self):
        # GIVEN
        stable = any_stable()

        border_router = network_data.BorderRouter(any_border_router_16(), any_prf(
        ), any_p(), any_s(), any_d(), any_c(), any_r(), any_o(), any_n(), stable)

        # WHEN
        actual_stable = border_router.stable

        # THEN
        self.assertEqual(stable, actual_stable)


class TestBorderRouterFactory(unittest.TestCase):

    def test_should_create_BorderRouter_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        border_router_16 = any_border_router_16()
        prf = any_prf()
        p = any_p()
        s = any_s()
        d = any_d()
        c = any_c()
        r = any_r()
        o = any_o()
        n = any_n()
        stable = any_stable()

        factory = network_data.BorderRouterFactory()

        data = convert_border_router_to_bytearray(
            network_data.BorderRouter(border_router_16, prf, p, s, d, c, r, o, n, stable))

        message_info = common.MessageInfo()
        message_info.stable = stable

        # WHEN
        actual_border_router = factory.parse(io.BytesIO(data), message_info)

        # THEN
        self.assertTrue(isinstance(actual_border_router, network_data.BorderRouter))
        self.assertEqual(border_router_16, actual_border_router.border_router_16)
        self.assertEqual(prf, actual_border_router.prf)
        self.assertEqual(p, actual_border_router.p)
        self.assertEqual(s, actual_border_router.s)
        self.assertEqual(d, actual_border_router.d)
        self.assertEqual(c, actual_border_router.c)
        self.assertEqual(r, actual_border_router.r)
        self.assertEqual(o, actual_border_router.o)
        self.assertEqual(n, actual_border_router.n)
        self.assertEqual(stable, actual_border_router.stable)


class TestLowpanId(unittest.TestCase):

    def test_should_return_c_value_when_c_property_is_called(self):
        # GIVEN
        c = any_c()

        lowpan_id = network_data.LowpanId(c, any_cid(), any_context_length(), any_stable())

        # WHEN
        actual_c = lowpan_id.c

        # THEN
        self.assertEqual(c, actual_c)

    def test_should_return_cid_value_when_cid_property_is_called(self):
        # GIVEN
        cid = any_cid()

        lowpan_id = network_data.LowpanId(any_c(), cid, any_context_length(), any_stable())

        # WHEN
        actual_cid = lowpan_id.cid

        # THEN
        self.assertEqual(cid, actual_cid)

    def test_should_return_context_length_value_when_context_length_property_is_called(self):
        # GIVEN
        context_length = any_context_length()

        lowpan_id = network_data.LowpanId(any_c(), any_cid(), context_length, any_stable())

        # WHEN
        actual_context_length = lowpan_id.context_length

        # THEN
        self.assertEqual(context_length, actual_context_length)

    def test_should_return_stable_value_when_stable_property_is_called(self):
        # GIVEN
        stable = any_stable()

        lowpan_id = network_data.LowpanId(any_c(), any_cid(), any_context_length(), stable)

        # WHEN
        actual_stable = lowpan_id.stable

        # THEN
        self.assertEqual(stable, actual_stable)


class TestLowpanIdFactory(unittest.TestCase):

    def test_should_create_LowpanId_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        c = any_c()
        cid = any_cid()
        context_length = any_context_length()
        stable = any_stable()

        factory = network_data.LowpanIdFactory()

        data = convert_lowpan_id_to_bytearray(network_data.LowpanId(c, cid, context_length, stable))

        message_info = common.MessageInfo()
        message_info.stable = stable

        # WHEN
        actual_lowpan_id = factory.parse(io.BytesIO(data), message_info)

        # THEN
        self.assertTrue(isinstance(actual_lowpan_id, network_data.LowpanId))
        self.assertEqual(c, actual_lowpan_id.c)
        self.assertEqual(cid, actual_lowpan_id.cid)
        self.assertEqual(context_length, actual_lowpan_id.context_length)


class TestService(unittest.TestCase):

    def test_should_return_t_value_when_t_property_is_called(self):
        # GIVEN
        t = any_t()

        service = network_data.Service(t, any_id(), any_enterprise_number(), any_service_data_length(),
                                       any_service_data(), any_service_sub_tlvs(), any_stable())

        # WHEN
        actual_t = service.t

        # THEN
        self.assertEqual(t, actual_t)

    def test_should_return_id_value_when_id_property_is_called(self):
        # GIVEN
        _id = any_id()

        service = network_data.Service(any_t(), _id, any_enterprise_number(), any_service_data_length(),
                                       any_service_data(), any_service_sub_tlvs(), any_stable())

        # WHEN
        actual_id = service.id

        # THEN
        self.assertEqual(_id, actual_id)

    def test_should_return_enterprise_number_value_when_enterprise_number_property_is_called(self):
        # GIVEN
        enterprise_number = any_enterprise_number()

        service = network_data.Service(any_t(), any_id(), enterprise_number, any_service_data_length(),
                                       any_service_data(), any_service_sub_tlvs(), any_stable())

        # WHEN
        actual_enterprise_number = service.enterprise_number

        # THEN
        self.assertEqual(enterprise_number, actual_enterprise_number)

    def test_should_return_service_data_length_value_when_service_data_length_property_is_called(self):
        # GIVEN
        service_data_length = any_service_data_length()

        service = network_data.Service(any_t(), any_id(), any_enterprise_number(), service_data_length,
                                       any_service_data(), any_service_sub_tlvs(), any_stable())

        # WHEN
        actual_service_data_length = service.service_data_length

        # THEN
        self.assertEqual(service_data_length, actual_service_data_length)

    def test_should_return_service_data_value_when_service_data_property_is_called(self):
        # GIVEN
        service_data = any_service_data()

        service = network_data.Service(any_t(), any_id(), any_enterprise_number(), any_service_data_length(),
                                       service_data, any_service_sub_tlvs(), any_stable())

        # WHEN
        actual_service_data = service.service_data

        # THEN
        self.assertEqual(service_data, actual_service_data)

    def test_should_return_sub_tlvs_value_when_sub_tlvs_property_is_called(self):
        # GIVEN
        sub_tlvs = any_service_sub_tlvs()

        service = network_data.Service(any_t(), any_id(), any_enterprise_number(), any_service_data_length(),
                                       any_service_data(), sub_tlvs, any_stable())

        # WHEN
        actual_sub_tlvs = service.sub_tlvs

        # THEN
        self.assertEqual(sub_tlvs, actual_sub_tlvs)

    def test_should_return_stable_value_when_stable_property_is_called(self):
        # GIVEN
        stable = any_stable()

        service = network_data.Service(any_t(), any_id(), any_enterprise_number(), any_service_data_length(),
                                       any_service_data(), any_service_sub_tlvs(), stable)

        # WHEN
        actual_stable = service.stable

        # THEN
        self.assertEqual(stable, actual_stable)


class TestServiceSubTlvsFactory(unittest.TestCase):

    def test_should_create_SubTlvs_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        sub_tlvs = any_service_sub_tlvs()

        factory = network_data.ServiceSubTlvsFactory(config.create_default_network_data_service_sub_tlvs_factories())

        data = convert_service_sub_tlvs_to_bytearray(sub_tlvs)

        # WHEN
        actual_sub_tlvs = factory.parse(io.BytesIO(data), common.MessageInfo())

        # THEN
        self.assertTrue(isinstance(actual_sub_tlvs, list))
        self.assertEqual(sub_tlvs, actual_sub_tlvs)


class TestServiceFactory(unittest.TestCase):

    def test_should_create_Service_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        t = any_t()
        _id = any_id()
        enterprise_number = any_enterprise_number()
        service_data_length = any_service_data_length()
        service_data = any_service_data(service_data_length)
        sub_tlvs = any_service_sub_tlvs()
        stable = any_stable()

        factory = network_data.ServiceFactory(config.create_default_network_data_service_sub_tlvs_factory())

        data = convert_service_to_bytearray(network_data.Service(
            t, _id, enterprise_number, service_data_length, service_data, sub_tlvs, stable))

        message_info = common.MessageInfo()
        message_info.stable = stable

        # WHEN
        actual_service = factory.parse(io.BytesIO(data), message_info)

        # THEN
        self.assertTrue(isinstance(actual_service, network_data.Service))
        self.assertEqual(t, actual_service.t)
        self.assertEqual(_id, actual_service.id)
        self.assertEqual(enterprise_number, actual_service.enterprise_number)
        self.assertEqual(service_data_length, actual_service.service_data_length)
        self.assertEqual(service_data, actual_service.service_data)
        self.assertEqual(sub_tlvs, actual_service.sub_tlvs)


class TestServer(unittest.TestCase):

    def test_should_return_server_16_value_when_server_16_property_is_called(self):
        # GIVEN
        server_16 = any_server_16()

        server = network_data.Server(server_16, any_server_data(), any_stable())

        # WHEN
        actual_server_16 = server.server_16

        # THEN
        self.assertEqual(server_16, actual_server_16)

    def test_should_return_server_data_value_when_server_data_property_is_called(self):
        # GIVEN
        server_data = any_server_data()

        server = network_data.Server(any_server_16(), server_data, any_stable())

        # WHEN
        actual_server_data = server.server_data

        # THEN
        self.assertEqual(server_data, actual_server_data)

    def test_should_return_stable_value_when_stable_property_is_called(self):
        # GIVEN
        stable = any_stable()

        server = network_data.Server(any_server_16(), any_server_data(), stable)

        # WHEN
        actual_stable = server.stable

        # THEN
        self.assertEqual(stable, actual_stable)


class TestServerFactory(unittest.TestCase):

    def test_should_create_Server_from_bytearray_when_parse_method_is_called(self):
        # GIVEN
        server_16 = any_server_16()
        server_data = any_server_data()
        stable = any_stable()

        factory = network_data.ServerFactory()

        data = convert_server_to_bytearray(network_data.Server(server_16, server_data, stable))

        message_info = common.MessageInfo()
        message_info.stable = stable

        # WHEN
        actual_server = factory.parse(io.BytesIO(data), message_info)

        # THEN
        self.assertTrue(isinstance(actual_server, network_data.Server))
        self.assertEqual(server_16, actual_server.server_16)
        self.assertEqual(server_data, actual_server.server_data)
        self.assertEqual(stable, actual_server.stable)


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