from typing import cast
import pytest
from xml.etree.ElementTree import fromstring

import pymasep as pm
from test.unit.mocks.game_mock import GameMock


def new_environment_engine(cfg):
    env = pm.engine.EnvironmentEngine()
    game = GameMock(cfg=cfg)
    env.game = game
    return env


@pytest.fixture(scope="function")
def mock_environment_engine():
    yield new_environment_engine(cfg=None)


def test_create_object_agent_control_interface_xml(mock_environment_engine):
    agent_xml_str = '<Agent name="agent1" control="interface">' \
                    '<ObjectState name="state">' \
                    '<Characteristic name="Step0"><int>0</int></Characteristic>' \
                    '</ObjectState>' \
                    '</Agent>'
    xml_node = fromstring(agent_xml_str)
    ag = cast(pm.common.Agent, mock_environment_engine.create_object(name='', xml_node=xml_node))
    ag.from_xml(environment=mock_environment_engine, xml_node=xml_node)

    assert isinstance(ag.controller, pm.engine.ExternalController)


def test_create_object_agent_control_interface_xml_no_subelement(mock_environment_engine):
    agent_xml_str = '<Agent name="Joueur1" control="interface" ' \
                    'template="DefaultAgentTemplate" initializer="objectinitializer"/>'
    xml_node = fromstring(agent_xml_str)
    ag = cast(pm.common.Agent, mock_environment_engine.create_object(name='', xml_node=xml_node))
    ag.from_xml(environment=mock_environment_engine, xml_node=xml_node)

    assert isinstance(ag.controller, pm.engine.ExternalController)


def test_create_object_agent_control_interface_template(mock_environment_engine):
    expected_name = 'AgentName1'
    game = mock_environment_engine.game
    obj_parent = mock_environment_engine.create_base_object('parent',
                                                            template=game.templates['DefaultStateTemplate'])

    ag = mock_environment_engine.create_object(name=expected_name, template=game.templates['DefaultAgentTemplate'],
                                               xml_node=None, parent=obj_parent, control='interface')
    ag = cast(pm.common.Agent, ag)

    assert isinstance(ag.controller, pm.engine.ExternalController)
    assert ag.control == 'interface'
