"""@package docstring
B-ASIC Core Operations Module.
TODO: More info.
"""

from numbers import Number

from b_asic.port import InputPort, OutputPort
from b_asic.operation import Operation
from b_asic.basic_operation import BasicOperation
from b_asic.graph_id import GraphIDType


class Input(Operation):
	"""Input operation.
	TODO: More info.
	"""

	# TODO: Implement all functions.
	pass


class Constant(BasicOperation):
	"""Constant value operation.
	TODO: More info.
	"""

	def __init__(self, value: Number):
		"""Construct a Constant."""
		super().__init__()
		self._output_ports = [OutputPort(1, self)] # TODO: Generate appropriate ID for ports.
		self._parameters["value"] = value

	def evaluate(self, inputs: list) -> list:
		return [self.param("value")]

	def type_name(self) -> GraphIDType:
		return "const"

class Addition(BasicOperation):
	"""Binary addition operation.
	TODO: More info.
	"""

	def __init__(self):
		"""Construct an Addition."""
		super().__init__()
		self._input_ports = [InputPort(1, self), InputPort(1, self)] # TODO: Generate appropriate ID for ports.
		self._output_ports = [OutputPort(1, self)] # TODO: Generate appropriate ID for ports.

	def evaluate(self, inputs: list) -> list:
		return [inputs[0] + inputs[1]]

	def type_name(self) -> GraphIDType:
		return "add"


class ConstantMultiplication(BasicOperation):
	"""Unary constant multiplication operation.
	TODO: More info.
	"""

	def __init__(self, coefficient: Number):
		"""Construct a ConstantMultiplication."""
		super().__init__()
		self._input_ports = [InputPort(1), self] # TODO: Generate appropriate ID for ports.
		self._output_ports = [OutputPort(1, self)] # TODO: Generate appropriate ID for ports.
		self._parameters["coefficient"] = coefficient

	def evaluate(self, inputs: list) -> list:
		return [inputs[0] * self.param("coefficient")]

	def type_name(self) -> GraphIDType:
		return "const_mul"

# TODO: More operations.