
import re

from catalyst import log
from catalyst.support import CatalystError


class ParserBase():

    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:
            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*#.*$')

        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('"')

                # 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 = 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:
                    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)
