# 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
