from unittest import TestCase
from xml.etree.ElementTree import tostring, fromstring

import pymasep.common

from test.unit.mocks.game_mock import GameMock


class TestAction(TestCase):

    def test_init(self):
        env = pymasep.common.Environment()
        ac = pymasep.common.Action(environment=env, action_type=GameMock.ACTION_TYPE_1)
        self.assertEqual(env, ac.environment)
        self.assertEqual(GameMock.ACTION_TYPE_1, ac.type)
        self.assertEqual(dict(), ac.params)

    def test_to_xml_transformed(self):
        expected_xml_str = '<Action type="1">' \
                           '<ActionParameter name="OneParam">' \
                           '<Characteristic name="Charac1" state="run"><int>1</int></Characteristic>' \
                           '</ActionParameter>' \
                           '<ActionParameter name="ParamTwo">' \
                           '<tuple><item><int>1</int></item><item><int>2</int></item></tuple>' \
                           '</ActionParameter>' \
                           '' \
                           '</Action>'
        env = pymasep.common.Environment()
        game = GameMock()
        env.game = game
        action = pymasep.common.Action(env, GameMock.ACTION_TYPE_1)
        charac = env.create_object(name='Charac1', template=env.game.templates['CharacInt'])
        charac.value = 1
        action.add_parameter('OneParam', charac)
        t = (1, 2)
        action.add_parameter('ParamTwo', t)

        xml_str_result = tostring(action.to_xml(), encoding='unicode')
        self.assertEqual(expected_xml_str, xml_str_result)

    def test_from_xml(self):
        action_xml_str = '<Action type="1">' \
                         '<ActionParameter name="OneParam">' \
                         '<Characteristic name="CharacInt" state="run"><int>1</int></Characteristic>' \
                         '</ActionParameter>' \
                         '<ActionParameter name="ParamTwo">' \
                         '<tuple><item><int>1</int></item><item><int>2</int></item></tuple>' \
                         '</ActionParameter>' \
                         '</Action>'
        xml_node = fromstring(action_xml_str)
        env = pymasep.common.Environment()
        game = GameMock()
        env.game = game
        action = env.create_action(GameMock.ACTION_NO_ACTION)
        action.from_xml(environment=env, xml_node=xml_node)
        self.assertIsInstance(action, pymasep.common.Action)
        self.assertEqual(1, action.type)
        self.assertEqual(2, len(action.params))
        self.assertIsInstance(action.params['OneParam'], pymasep.common.Characteristic)
        self.assertEqual(action.params['ParamTwo'], (1, 2))

    def test_from_xml_param_is_action(self):
        action_xml_str = '<Action type="1">' \
                         '<ActionParameter name="action">' \
                         '<Action type="5">' \
                         '<ActionParameter name="pos">' \
                         '<list>' \
                         '<item>' \
                         '<tuple><item><int>14</int></item><item><int>18</int></item></tuple>' \
                         '</item></list>' \
                         '</ActionParameter>' \
                         '</Action>' \
                         '</ActionParameter>' \
                         '</Action>'
        xml_node = fromstring(action_xml_str)
        env = pymasep.common.Environment()
        game = GameMock()
        env.game = game
        action = env.create_action(GameMock.ACTION_NO_ACTION)
        action.from_xml(environment=env, xml_node=xml_node)
        self.assertIsInstance(action, pymasep.common.Action)
        self.assertEqual(1, action.type)
        self.assertEqual(1, len(action.params))
        self.assertIsInstance(action.params['action'], pymasep.common.Action)
        self.assertEqual(action.params['action'].params['pos'], [(14, 18)])

    def test_id_str(self):
        action_xml_str = '<Action type="1">' \
                         '<ActionParameter name="OneParam">' \
                         '<Characteristic name="Charac1" state="run"><int>1</int></Characteristic>' \
                         '</ActionParameter>' \
                         '<ActionParameter name="ParamTwo">' \
                         '<tuple><item><int>1</int></item><item><int>2</int></item></tuple>' \
                         '</ActionParameter>' \
                         '</Action>'
        xml_node = fromstring(action_xml_str)
        env = pymasep.common.Environment()
        game = GameMock()
        env.game = game
        action = env.create_action(GameMock.ACTION_NO_ACTION)
        action.from_xml(environment=env, xml_node=xml_node)

        id_str = action.id_str()

        self.assertEqual('action1OneParamCharac11ParamTwo(1,2)', id_str)
