import random

from environments.factory.factory_battery import BatteryFactory, BatteryProperties
from environments.factory.factory_dest import DestFactory
from environments.factory.factory_dirt import DirtFactory, DirtProperties
from environments.factory.factory_item import ItemFactory


# noinspection PyAbstractClass
class DirtItemFactory(ItemFactory, DirtFactory):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)


# noinspection PyAbstractClass
class DirtBatteryFactory(DirtFactory, BatteryFactory):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)


# noinspection PyAbstractClass
class DirtDestItemFactory(ItemFactory, DirtFactory, DestFactory):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)


if __name__ == '__main__':
    from environments.utility_classes import AgentRenderOptions as ARO, ObservationProperties

    render = True

    dirt_props = DirtProperties(1, 0.05, 0.1, 3, 1, 20, 0)

    obs_props = ObservationProperties(render_agents=ARO.COMBINED, omit_agent_self=True,
                                      pomdp_r=2, additional_agent_placeholder=None)

    move_props = {'allow_square_movement': True,
                  'allow_diagonal_movement': False,
                  'allow_no_op': False}

    factory = DirtBatteryFactory(n_agents=5, done_at_collision=False,
                                 level_name='rooms', max_steps=400,
                                 obs_prop=obs_props, parse_doors=True,
                                 record_episodes=True, verbose=True,
                                 btry_prop=BatteryProperties(),
                                 mv_prop=move_props, dirt_prop=dirt_props
                                 )

    # noinspection DuplicatedCode
    n_actions = factory.action_space.n - 1
    _ = factory.observation_space

    for epoch in range(4):
        random_actions = [[random.randint(0, n_actions) for _
                           in range(factory.n_agents)] for _
                          in range(factory.max_steps + 1)]
        env_state = factory.reset()
        r = 0
        for agent_i_action in random_actions:
            env_state, step_r, done_bool, info_obj = factory.step(agent_i_action)
            r += step_r
            if render:
                factory.render()
            if done_bool:
                break
        print(f'Factory run {epoch} done, reward is:\n    {r}')
pass