from xml.etree.ElementTree import tostring, fromstring

import pymasep.common as common
import pymasep.common.exception as exception


def test_init(mock_environment):
    expected_name = 'BaseObject1'

    bo = common.BaseObject(environment=mock_environment,
                           name=expected_name,
                           template=mock_environment.game.templates['CharacInt'])

    assert isinstance(bo, common.BaseObject)
    assert bo.environment == mock_environment
    assert bo.name == expected_name
    assert bo.parent is None
    assert mock_environment.game.templates['CharacInt'] == bo.template
    assert bo.nature is None


def test_init_no_template_should_except(mock_environment):
    try:
        _ = common.BaseObject(environment=mock_environment, name='BaseObject1')
        assert False
    except exception.CreationException as e:
        assert str(e) == 'Need template or xml_node'


def test_init_with_parent(mock_environment):
    expected_name = 'BaseObject1'
    bo_parent = common.BaseObject(environment=mock_environment, name='Parent1',
                                  template=mock_environment.game.templates['DefaultObjectStateTemplate'])

    bo = common.BaseObject(environment=mock_environment, name=expected_name,
                           parent=bo_parent,
                           template=mock_environment.game.templates['CharacInt'])

    assert bo.parent == bo_parent


def test_get_full_name_no_parent(mock_environment):
    expected_name = 'BaseObject1'

    bo = common.BaseObject(environment=mock_environment, name=expected_name,
                           template=mock_environment.game.templates['CharacInt'])

    assert bo.get_fullname() == expected_name


def test_get_full_name_with_parent(mock_environment):
    expected_name = 'BaseObject1'
    bo_parent = common.BaseObject(environment=mock_environment, name='Parent1',
                                  template=mock_environment.game.templates['DefaultObjectStateTemplate'])

    bo = common.BaseObject(environment=mock_environment, name=expected_name, parent=bo_parent,
                           template=mock_environment.game.templates['CharacInt'])

    assert bo.get_fullname() == bo_parent.get_fullname() + '.' + expected_name


def test_to_xml_no_parent_transformed(mock_environment):
    expected_xml_str = '<BaseObject name="BaseObject1" state="init" />'
    bo = common.BaseObject(environment=mock_environment, name='BaseObject1',
                           template=mock_environment.game.templates['CharacInt'])
    bo.state = 'init'

    xml_str_result = tostring(bo.to_xml(), encoding='unicode')

    assert xml_str_result == expected_xml_str


def test_to_xml_state_run(mock_environment):
    expected_xml_str = '<BaseObject name="BaseObject1" state="run" />'
    bo = common.BaseObject(environment=mock_environment, name='BaseObject1',
                           template=mock_environment.game.templates['CharacInt'])
    bo.state = 'run'
    bo.initializer = mock_environment.game.initializers['DummyInitializer']

    xml_str_result = tostring(bo.to_xml(), encoding='unicode')
    assert xml_str_result == expected_xml_str


def test_to_xml_with_initializer(mock_environment):
    base_xml_str = '<BaseObject name="BO1" template="DefaultBaseObjectTemplate" initializer="DummyInitializer" />'
    expected_xml_str = '<BaseObject name="BO1" nature="baseobject" initializer="DummyInitializer" />'
    xml_node = fromstring(base_xml_str)
    base_object = mock_environment.create_base_object(name='', xml_node=xml_node)
    base_object.from_xml(mock_environment, xml_node)

    xml_str_result = tostring(base_object.to_xml(), encoding='unicode')

    assert xml_str_result == expected_xml_str


def test_from_xml_without_nature(mock_environment):
    base_xml_str = '<BaseObject name="BO1" state="run"></BaseObject>'
    xml_node = fromstring(base_xml_str)
    base_object = mock_environment.create_base_object(name='', xml_node=xml_node)

    base_object.from_xml(mock_environment, xml_node)

    assert type(base_object) == common.BaseObject
    assert base_object.name == 'BO1'
    assert base_object.nature is None
    assert base_object.parent is None
    assert base_object.state == 'run'


def test_from_xml_no_name(mock_environment):
    base_xml_str = '<BaseObject state="run"></BaseObject>'
    xml_node = fromstring(base_xml_str)
    base_object = mock_environment.create_base_object(name='BO1', xml_node=xml_node)

    base_object.from_xml(mock_environment, xml_node)

    assert type(base_object) == common.BaseObject
    assert base_object.name == 'BO1'
    assert base_object.nature is None
    assert base_object.parent is None
    assert base_object.state == 'run'


def test_from_xml_name_xml_and_param(mock_environment):
    base_xml_str = '<BaseObject name="BO1" state="run"></BaseObject>'
    xml_node = fromstring(base_xml_str)
    base_object = mock_environment.create_base_object(name='BO2', xml_node=xml_node)

    base_object.from_xml(mock_environment, xml_node)

    assert type(base_object) == common.BaseObject
    assert base_object.name == 'BO1'
    assert base_object.nature is None
    assert base_object.parent is None
    assert base_object.state == 'run'


def test_from_xml_with_nature(mock_environment):
    base_xml_str = '<BaseObject name="DefaultBaseObjectTemplate" nature="baseobject" state="run"></BaseObject>'
    xml_node = fromstring(base_xml_str)
    base_object = mock_environment.create_base_object(name='', xml_node=xml_node)

    base_object.from_xml(mock_environment, xml_node)

    assert base_object.nature == 'baseobject'


def test_from_xml_with_initializer(mock_environment):
    base_xml_str = '<BaseObject name="BO1" template="DefaultBaseObjectTemplate" initializer="DummyInitializer" />'
    xml_node = fromstring(base_xml_str)
    base_object = mock_environment.create_base_object(name='', xml_node=xml_node)

    base_object.from_xml(mock_environment, xml_node)

    assert base_object.nature == 'baseobject'
    assert base_object.initializer == mock_environment.game.initializers['DummyInitializer']


def test_id_str(mock_environment):
    base_xml_str = '<BaseObject name="DefaultBaseObjectTemplate" state="run"></BaseObject>'
    xml_node = fromstring(base_xml_str)
    base_object = mock_environment.create_base_object(name='', xml_node=xml_node)
    base_object.from_xml(mock_environment, xml_node)

    id_str = base_object.id_str()

    assert id_str == 'DefaultBaseObjectTemplate'
