from netaddr import IPNetwork, IPAddress

import netaddr.core

from bspump.declarative.abc import Expression
from ..value.valueexpr import VALUE


class IP_INSUBNET(Expression):
	"""
	Checks if expression is of given subnet.
	"""

	Attributes = {
		"Value": ["*"],  # TODO: This ...
		"Subnet": ["*"],  # TODO: This ...
	}

	Category = "IP"


	def __init__(self, app, *, arg_subnet, arg_what):
		super().__init__(app)

		if isinstance(arg_what, Expression):
			self.Value = arg_what
		else:
			self.Value = VALUE(app, value=arg_what)


		if isinstance(arg_subnet, Expression):
			self.Subnet = arg_subnet
		else:
			self.Subnet = VALUE(app, value=arg_subnet)


	def __call__(self, context, event, *args, **kwargs):
		value = self.Value(context, event, *args, **kwargs)
		subnet = self.Subnet(context, event, *args, **kwargs)

		try:
			if isinstance(subnet, list):
				for element in subnet:
					if IPAddress(value) in IPNetwork(element):
						return True
			else:
				return IPAddress(value) in IPNetwork(subnet)

		except netaddr.core.AddrFormatError:
			# IP address could not be detected
			return None

		return False
