# vim: tabstop=4 shiftwidth=4 softtabstop=4
# -*- coding: utf-8 -*-
#

import re
from ftg.utils.common import CommonUtils
from ftg.flow_table import FlowTable
from ftg.flow_priority import FlowPriority
from ftg.flow_entry import FlowEntry


class BaseParser():

    def __init__(self, util, dump_file):
        self.util = util
        self.dump_file = dump_file
        self.tables = {}

    def regist_flow(self, table_no, priority_no, match_exp, instructions, counter=""):
        exist_table = True
        exist_priority = True

        if not table_no in self.tables:
            exist_table = False
            exist_priority = False
        elif not priority_no in self.tables[table_no].get_priorities():
            exist_priority = False

        if exist_table and exist_priority:
            entry = FlowEntry(match_exp, instructions)
            self.tables[table_no].get_priority(
                priority_no).add_flow_entries(entry)
        elif exist_table and exist_priority == False:
            priority = FlowPriority(priority_no)
            entry = FlowEntry(match_exp, instructions)
            priority.add_flow_entries(entry)
            self.tables[table_no].add_priorities({str(priority_no): priority})
        else:
            entry = FlowEntry(match_exp, instructions)
            priority = FlowPriority(priority_no)
            table = FlowTable(table_no)
            priority.add_flow_entries(entry)
            table.add_priorities({str(priority_no): priority})
            self.tables.update({str(table_no): table})

    def get_tables(self):
        return self.tables

    def _parse_actions_with_bracket(self, instruction, actions):
        if self.util.d_push(re.match(r'(.*),(.*?\(.*?\))(.*)', instruction)) is not None:
            match = self.util.d_pop()
            if match.group(1).find("(") != -1:
                self._parse_actions_with_bracket(match.group(1), actions)
            else:
                actions.extend(self._split_action(match.group(1)))

            actions.append(match.group(2))
            if match.group(3).strip() != "":
                actions.extend(self._split_action(match.group(3)))
        elif self.util.d_push(re.match(r'(?<!,)(.*?\(.*?\))(.*)', instruction)) is not None:
            match = self.util.d_pop()
            if match.group(1).strip() != "":
                actions.append(match.group(1))

            if match.group(2).strip() != "":
                if match.group(2).find("(") != -1:
                    self._parse_actions_with_bracket(match.group(2), actions)
                else:
                    actions.extend(self._split_action(match.group(2)))
        else:
            actions.extend(self._split_action(instruction))

        return actions

    def _split_action(self, action):
        action = re.sub(r'^,', '', action)
        actions = action.split(',')
        return actions
