import abc

import gym.spaces

from metaworlds.worlds.core.world import ParametricWorld


class MetaWorld(ParametricWorld):
    """A :obj:`World` whose state space is a :obj:`POMDPDescriptor`.

    Args:
        podmp_space(:obj:`gym.Space`): A space representing the
            POMDPs generated by this :obj:`MetaWorld`
    """

    def __init__(self, pomdp_space):
        self.observation_space = pomdp_space

    def render(self, mode='human'):
        print(self.pomdp)


class UniformRandomMetaWorld(MetaWorld):
    """A :obj:`MetaWorld` which chooses the next POMDP uniformly at random."""

    action_space = gym.spaces.Discrete(0)

    def reset(self):
        return self.observation_space.sample()

    def step(self, action):
        return self.observation_space.sample(), None, False, dict()


class RoundRobinMetaWorld(MetaWorld):
    """A :obj:`MetaWorld` which produces a discrete set of POMDPs in a round
    robin order.
    """
    action_space = gym.spaces.Discrete(0)

    def __init__(self, pomdp_space):
        if not isinstance(pomdp_space, gym.spaces.Discrete):
            raise ValueError('pomdp_space must be `gym.spaces.Discrete, but '
                             '{} provided.'.format(pomdp_space))

        super().__init__(pomdp_space)
        self._state = 0

    def reset(self):
        self._state = 0
        return self._state

    def step(self, action):
        self._state = (self._state + 1) % self.observation_space.n
        return self._state, None, False, dict()
