# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import html
import pyparsing as pp

# Some useful primitives
ident = pp.Word(pp.alphas + "_", pp.alphas + pp.nums + "_")
intNum = pp.Word(pp.nums)
hexNum = pp.Literal("0x") + pp.Word(pp.hexnums)
octalNum = pp.Literal("0") + pp.Word("01234567")
integer = (hexNum | octalNum | intNum) + \
    pp.Optional(pp.Literal("ULL") | pp.Literal("LL") | pp.Literal("L"))
floatNum = pp.Regex(r'\d+(\.\d*)?([eE]\d+)?') + pp.Optional(pp.Literal("f"))
char = pp.Literal("'") + pp.Word(pp.printables, exact=1) + pp.Literal("'")
arrayIndex = integer | ident

lbracket = pp.Literal("(").suppress()
rbracket = pp.Literal(")").suppress()
lbrace = pp.Literal("{").suppress()
rbrace = pp.Literal("}").suppress()
comma = pp.Literal(",").suppress()
equals = pp.Literal("=").suppress()
dot = pp.Literal(".").suppress()
semicolon = pp.Literal(";").suppress()

# initializer := { [member = ] (variable | expression | { initializer } ) }
typeName = ident
varName = ident
typeSpec = pp.Optional("unsigned") + \
           pp.oneOf("int long short float double char u8 i8 void") + \
           pp.Optional(pp.Word("*"), default="")
typeCast = pp.Combine( "(" + ( typeSpec | typeName ) + ")" ).suppress()

string = pp.Combine(pp.OneOrMore(pp.QuotedString(quoteChar='"',
    escChar='\\', multiline=True)), adjacent=False)
literal = pp.Optional(typeCast) + (integer | floatNum | char | string)
var = pp.Combine(pp.Optional(typeCast) + varName +
    pp.Optional("[" + arrayIndex + "]"))

# This could be more complete, but suffices for our uses
expr = (literal | var)

"""Parse and render a block of text into a Python dictionary."""
class Parser(object):
    """Compiled PyParsing BNF"""
    _parser = None

    def __init__(self):
        super(Parser, self).__init__()
        self._parser = self.BNF()

    def BNF(self):
        raise NotImplementedError

    def item(self, item):
        raise NotImplementedError

    def parse(self, input):
        item = self._parser.parseString(input).asList()
        return self.item(item)


"""Parser for function-like macros - without the closing semi-colon."""
class ParserFunctionMacro(Parser):
    def BNF(self):
        # VLIB_CONFIG_FUNCTION (unix_config, "unix")
        macroName = ident
        params = pp.Group(pp.ZeroOrMore(expr + comma) + expr)
        macroParams = lbracket + params + rbracket

        return macroName + macroParams

    def item(self, item):
        r = {
            "macro": item[0],
            "name": item[1][1],
            "function": item[1][0],
        }

        return r


"""Parser for function-like macros with a closing semi-colon."""
class ParseFunctionMacroStmt(ParserFunctionMacro):
    def BNF(self):
        # VLIB_CONFIG_FUNCTION (unix_config, "unix");
        function_macro = super(ParseFunctionMacroStmt, self).BNF()
        mi = function_macro + semicolon
        mi.ignore(pp.cppStyleComment)

        return mi


"""
Parser for our struct initializers which are composed from a
function-like macro, equals sign, and then a normal C struct initializer
block.
"""
class MacroInitializer(ParserFunctionMacro):
    def BNF(self):
        # VLIB_CLI_COMMAND (show_sr_tunnel_command, static) = {
        #    .path = "show sr tunnel",
        #    .short_help = "show sr tunnel [name <sr-tunnel-name>]",
        #    .function = show_sr_tunnel_fn,
        # };
        cs = pp.Forward()


        member = pp.Combine(dot + varName + pp.Optional("[" + arrayIndex + "]"),
            adjacent=False)
        value = (expr | cs)

        entry = pp.Group(pp.Optional(member + equals, default="") + value)
        entries = (pp.ZeroOrMore(entry + comma) + entry + pp.Optional(comma)) | \
                  (pp.ZeroOrMore(entry + comma))

        cs << (lbrace + entries + rbrace)

        macroName = ident
        params = pp.Group(pp.ZeroOrMore(expr + comma) + expr)
        macroParams = lbracket + params + rbracket

        function_macro = super(MacroInitializer, self).BNF()
        mi = function_macro + equals + pp.Group(cs) + semicolon
        mi.ignore(pp.cppStyleComment)

        return mi

    def item(self, item):
        r = {
            "macro": item[0],
            "name": item[1][0],
            "params": item[2],
            "value": {},
        }

        for param in item[2]:
            r["value"][param[0]] = html.escape(param[1])

        return r
