"""
Utility functions needed by various modules.
"""
import struct
import requests
import re
import logging

pack4bytes_be = struct.Struct(">BBBB").pack
split_dot = re.compile("\.").split
pattern_ipresponse = re.compile("(<div class=\"title\"><strong>\d+\.\d+\.\d+\.\d+</strong></div>)")
pattern_ip = re.compile("\d+\.\d+\.\d+\.\d+")

logger = logging.getLogger("pra_framework")

def int_to_ip_str(ip_int):
	"""
	Convert an integer to an IP string
	return -- an IP address like "1.2.3.4"
	"""
	return "%d.%d.%d.%d" % ((ip_int >> 24), (ip_int >> 16) & 255, (ip_int >> 8) & 255, ip_int & 255)

def int_to_ip_bytes(ip_int):
	"""
	Convert an integer to an IP string (byte representation)
	return -- an IP address like b"\x00\x01\x02\x03"
	"""
	return pack4bytes_be((ip_int >> 24), (ip_int >> 16) & 255, (ip_int >> 8) & 255, ip_int & 255)

def ip_str_to_int(ip_str):
	a,b,c,d = split_dot(ip_str)
	return (int(a) << 24) | (int(b) << 16) | (int(c) << 8) | int(d)

def ip_str_to_bytes(ip_str):
	ip_digits = ip_str.split(".")
	return pack4bytes_be(int(ip_digits[0]), int(ip_digits[1]), int(ip_digits[2]), int(ip_digits[3]))

def get_external_ip():
	"""
	Get the IP address as seen from the internet.
	return -- IP address as string or None
	"""
	response = requests.get("http://www.wieistmeineip.de/")
	matches = pattern_ipresponse.search(response.text)

	if matches is None:
		raise Exception("no IP found in response")

	ip_html = matches.group(0)
	return pattern_ip.search(ip_html).group(0)


if __name__ == "__main__":
	print(get_external_ip())