from xml.etree.ElementTree import tostring, fromstring
from pymasep.communication import Message
from pymasep.common import Environment
from test.unit.mocks.game_mock import GameMock


def test_to_xml():
    expected_result = b'<Message msg_type="define" src_sub_app="1">' \
                      b'<dict>' \
                      b'<item key="test"><int>1</int></item>' \
                      b'<item key="test2"><str>string</str></item>' \
                      b'</dict>' \
                      b'</Message>'
    msg = Message(Message.MESSAGE_TYPE_DEFINE, {'test': 1, 'test2': 'string'}, '1')

    msg_xml = msg.to_xml()

    assert tostring(msg_xml) == expected_result


def test_to_xml_no_param():
    expected_result = b'<Message msg_type="define" src_sub_app="1" />'
    msg = Message(Message.MESSAGE_TYPE_DEFINE, None, '1')

    msg_xml = msg.to_xml()

    assert tostring(msg_xml) == expected_result


def test_to_xml_pymas_object_inside_native():
    base_xml_str = b'<BaseObject name="BO1" state="run" />'
    expected_result = b'<Message msg_type="define" src_sub_app="1">' \
                      b'<dict><item key="obj">' + base_xml_str + b'</item></dict></Message>'
    env = Environment()
    game = GameMock()
    env.game = game
    base_xml_node = fromstring(base_xml_str)
    base_object = env.create_object(xml_node=base_xml_node)

    msg = Message(Message.MESSAGE_TYPE_DEFINE, {'obj': base_object}, '1')

    result = msg.to_xml()

    assert tostring(result) == expected_result


def test_from_xml():
    xml_src = b'<Message msg_type="define" src_sub_app="1">' \
              b'<dict>' \
              b'<item key="test"><int>1</int></item>' \
              b'<item key="test2"><str>string</str></item>' \
              b'</dict>' \
              b'</Message>'
    msg = Message(0, None, '1')
    msg.from_xml(xml_node=fromstring(xml_src))

    assert msg.msg_type == Message.MESSAGE_TYPE_DEFINE
    assert msg.params == {'test': 1, 'test2': 'string'}
    assert msg.src_sub_app_id == '1'


def test_str():
    expected_result = '<Message msg_type="define" src_sub_app="1">' \
                      '<dict>' \
                      '<item key="test"><int>1</int></item>' \
                      '<item key="test2"><str>string</str></item>' \
                      '</dict>' \
                      '</Message>'
    msg = Message(Message.MESSAGE_TYPE_DEFINE, {'test': 1, 'test2': 'string'}, '1')

    msg_str = str(msg)

    assert msg_str == expected_result


def test_encode_decode():
    msg = Message(Message.MESSAGE_TYPE_DEFINE, {'test': 1, 'test2': 'string'}, '1')

    msg_byte = msg.to_bytes()
    result = Message(0, None, '1')
    result.from_bytes(msg_byte)

    assert msg == result
