
import re

from catalyst import log
from catalyst.support import CatalystError

class ParserBase(object):

	filename = ""
	lines = None
	values = None
	key_value_separator = "="
	multiple_values = False
	empty_values = True
	eval_none = False

	def __getitem__(self, key):
		return self.values[key]

	def get_values(self):
		return self.values

	def dump(self):
		dump = ""
		for x in self.values.keys():
			dump += x + " = " + repr(self.values[x]) + "\n"
		return dump

	def parse_file(self, filename):
		try:
			with open(filename, "r") as myf:
				self.lines = myf.readlines()
		except:
			raise CatalystError("Could not open file " + filename,
				print_traceback=True)
		self.filename = filename
		self.parse()

	def parse_lines(self, lines):
		self.lines = lines
		self.parse()

	def parse(self):
		values = {}
		cur_array = []

		trailing_comment=re.compile(r'\s*#.*$')
		#white_space=re.compile('\s+')

		for x, myline in enumerate(self.lines):
			myline = myline.strip()

			# Force the line to be clean
			# Remove Comments ( anything following # )
			myline = trailing_comment.sub("", myline)

			# Skip any blank lines
			if not myline:
				continue

			if self.key_value_separator in myline:
				# Split on the first occurence of the separator creating two strings in the array mobjs
				mobjs = myline.split(self.key_value_separator, 1)
				mobjs[1] = mobjs[1].strip().strip('"')

#				# Check that this key doesn't exist already in the spec
#				if mobjs[0] in values:
#					raise Exception("You have a duplicate key (" + mobjs[0] + ") in your spec. Please fix it")

				# Start a new array using the first element of mobjs
				cur_array = [mobjs[0]]
				if mobjs[1]:
					# do any variable substitiution embeded in it with
					# the values already obtained
					mobjs[1] = mobjs[1] % values
					if self.multiple_values:
						# split on white space creating additional array elements
#						subarray = white_space.split(mobjs[1])
						subarray = mobjs[1].split()
						cur_array += subarray
					else:
						cur_array += [mobjs[1]]

			# Else add on to the last key we were working on
			else:
				if self.multiple_values:
#					mobjs = white_space.split(myline)
#					cur_array += mobjs
					cur_array += myline.split()
				else:
					raise CatalystError("Syntax error: %s" % x, print_traceback=True)

			# XXX: Do we really still need this "single value is a string" behavior?
			if len(cur_array) == 2:
				values[cur_array[0]] = cur_array[1]
			else:
				values[cur_array[0]] = cur_array[1:]

		if not self.empty_values:
			# Make sure the list of keys is static since we modify inside the loop.
			for x in list(values.keys()):
				# Delete empty key pairs
				if not values[x]:
					log.warning('No value set for key "%s"; deleting', x)
					del values[x]

		if self.eval_none:
			# Make sure the list of keys is static since we modify inside the loop.
			for x in list(values.keys()):
				# reset None values
				if isinstance(values[x], str) and values[x].lower() in ['none']:
					log.info('None value found for key "%s"; reseting', x)
					values[x] = None
		self.values = values

class SpecParser(ParserBase):

	key_value_separator = ':'
	multiple_values = True
	empty_values = False
	eval_none = True

	def __init__(self, filename=""):
		if filename:
			self.parse_file(filename)

class ConfigParser(ParserBase):

	key_value_separator = '='
	multiple_values = False
	empty_values = True

	def __init__(self, filename=""):
		if filename:
			self.parse_file(filename)
