#!/usr/bin/python3

from random import randint, random, choice

class Choice:
	def __init__(self, **data):
		""" stores a dict.
		the keys are strings that indicate the next state,
		the values are lists that store the possible emissions in transition to that new state.
		"""
		self.data = data
		self.new_states = list(self.data.keys())

	def choose(self):
		new_state = choice(self.new_states)
		emission = choice(self.data[new_state])
		return new_state, emission

class SingleArgChoice:
	def __init__(self, kwarg):
		if len(kwarg) != 1:
			raise ValueError(
				f"{self.__class__.__name__} takes exactly one keyword argument!"
			)
		for self.next_state, self.value in kwarg.items():
			pass

class RandInt(SingleArgChoice):
	def __init__(self, **kwarg):
		super().__init__(kwarg)
		assert len(self.value) == 2
		assert type(self.value[0]) == int
		assert type(self.value[1]) == int

		self.minimum = self.value[0]
		self.maximum = self.value[1]

	def choose(self):
		number = randint(self.minimum, self.maximum)
		return self.next_state, f"{number} "

class FixedText(SingleArgChoice):
	def __init__(self, **kwarg):
		super().__init__(kwarg)
		self.text = self.value

	def choose(self):
		return self.next_state, self.text

class Network:
	def __init__(self, **choices):
		""" takes a dict,
		the keys are strings that name states,
		the values are the choices for new states and emissions possible in these states.
		the 'start' state and the 'stop' state have their respective special roles.
		"""
		self.choices = choices
		self.recursion_warning = 100

	def choose(self):
		state = 'start'
		emissions = []
		states = [state]
		while state != 'stop':
			state, emission = self.choices[state].choose()
			emissions.append(emission)
			states.append(states)
			if len(emissions) > self.recursion_warning:
				raise RecursionError(
					"there are over a hundred emissions. probably a bug!"
				)

		return emissions, states


