"""
Angle-Pipe Format Log Class
"""
LOG_LABELS = ['datetime', 'status', 'host', 'port', 'method', 'request',
              'version', 'bytes', 'time', 'user', 'ipaddress', 'referer',
              'useragent']


class Log():
    """
    Log Class
    Takes a log file and returns a parsed object

    The log can either be returned as a list of lists or
    as a list of dictionaries with the appropriate key added.

    Usage:
        l = Log(filename)
        l.as_dicts

    log_file -- file to open

    """
    def __init__(self, log_file):
        """
        Log Class
        Lines are automatically split on object creation

        log_file -- file to open

        """

        self.log_file = log_file
        # Read log and split by delimiter
        open_file = open(log_file, 'r')
        self.log = open_file.readlines()
        self.log = self.split_log_lines()

    @property
    def as_dicts(self):
        """
        Returns log as a list of dictionaries
        If this has been called once it won't regenerate the data instead
        using the data from last time.

        """
        # If already created reuse data
        if hasattr(self, 'dict_log'):
            return self.dict_log
        self.dict_log = [self.line_to_dict(l) for l in self.log]
        return self.dict_log

    @property
    def as_lists(self):
        """
        Returns log as a list of lists

        """
        return self.log

    def split_log_lines(self):
        """
        Splits all log lines in self.log
        Uses self.split_log_line

        """
        log = [self.split_log_line(l) for l in self.log]
        return log

    @staticmethod
    def split_log_line(log_line):
        """
        Splits an individual log line

        Splits line by "<|>" and request by " "

        """
        try:
            # Split by delimiter
            split_line = log_line.split('<|>')
            # Split Request into method|request|version
            try:
                method, request, version = split_line[4].split(' ')
            except:
                method = request = version = ""
            # [:4] = [Datetime, Status, host, port]
            line = split_line[:4] + [method, request, version]
            # [5:9] = [Bytes, Time, User, IP, Referer]
            line = line + split_line[5:10] + [split_line[10]]
            return line
        except:
            exc_str = "BAD LINE: %s" % log_line
            raise Exception(exc_str)

    @staticmethod
    def line_to_dict(line):
        """
        Matches the field names to the data
        and creates a dictionary for the line
        """
        out_line = dict(zip(LOG_LABELS, line))
        return out_line
