#!/usr/bin/env python3
#
# Mini-Kconfig parser
#
# Copyright (c) 2015 Red Hat Inc.
#
# Authors:
#  Paolo Bonzini <pbonzini@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2
# or, at your option, any later version.  See the COPYING file in
# the top-level directory.

import os
import sys
import re
import random

__all__ = [ 'KconfigDataError', 'KconfigParserError',
            'KconfigData', 'KconfigParser' ,
            'defconfig', 'allyesconfig', 'allnoconfig', 'randconfig' ]

def debug_print(*args):
    #print('# ' + (' '.join(str(x) for x in args)))
    pass

# -------------------------------------------
# KconfigData implements the Kconfig semantics.  For now it can only
# detect undefined symbols, i.e. symbols that were referenced in
# assignments or dependencies but were not declared with "config FOO".
#
# Semantic actions are represented by methods called do_*.  The do_var
# method return the semantic value of a variable (which right now is
# just its name).
# -------------------------------------------

class KconfigDataError(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return self.msg

allyesconfig = lambda x: True
allnoconfig = lambda x: False
defconfig = lambda x: x
randconfig = lambda x: random.randint(0, 1) == 1

class KconfigData:
    class Expr:
        def __and__(self, rhs):
            return KconfigData.AND(self, rhs)
        def __or__(self, rhs):
            return KconfigData.OR(self, rhs)
        def __invert__(self):
            return KconfigData.NOT(self)

        # Abstract methods
        def add_edges_to(self, var):
            pass
        def evaluate(self):
            assert False

    class AND(Expr):
        def __init__(self, lhs, rhs):
            self.lhs = lhs
            self.rhs = rhs
        def __str__(self):
            return "(%s && %s)" % (self.lhs, self.rhs)

        def add_edges_to(self, var):
            self.lhs.add_edges_to(var)
            self.rhs.add_edges_to(var)
        def evaluate(self):
            return self.lhs.evaluate() and self.rhs.evaluate()

    class OR(Expr):
        def __init__(self, lhs, rhs):
            self.lhs = lhs
            self.rhs = rhs
        def __str__(self):
            return "(%s || %s)" % (self.lhs, self.rhs)

        def add_edges_to(self, var):
            self.lhs.add_edges_to(var)
            self.rhs.add_edges_to(var)
        def evaluate(self):
            return self.lhs.evaluate() or self.rhs.evaluate()

    class NOT(Expr):
        def __init__(self, lhs):
            self.lhs = lhs
        def __str__(self):
            return "!%s" % (self.lhs)

        def add_edges_to(self, var):
            self.lhs.add_edges_to(var)
        def evaluate(self):
            return not self.lhs.evaluate()

    class Var(Expr):
        def __init__(self, name):
            self.name = name
            self.value = None
            self.outgoing = set()
            self.clauses_for_var = list()
        def __str__(self):
            return self.name

        def has_value(self):
            return not (self.value is None)
        def set_value(self, val, clause):
            self.clauses_for_var.append(clause)
            if self.has_value() and self.value != val:
                print("The following clauses were found for " + self.name, file=sys.stderr)
                for i in self.clauses_for_var:
                    print("    " + str(i), file=sys.stderr)
                raise KconfigDataError('contradiction between clauses when setting %s' % self)
            debug_print("=> %s is now %s" % (self.name, val))
            self.value = val

        # depth first search of the dependency graph
        def dfs(self, visited, f):
            if self in visited:
                return
            visited.add(self)
            for v in self.outgoing:
                v.dfs(visited, f)
            f(self)

        def add_edges_to(self, var):
            self.outgoing.add(var)
        def evaluate(self):
            if not self.has_value():
                raise KconfigDataError('cycle found including %s' % self)
            return self.value

    class Clause:
        def __init__(self, dest):
            self.dest = dest
        def priority(self):
            return 0
        def process(self):
            pass

    class AssignmentClause(Clause):
        def __init__(self, dest, value):
            KconfigData.Clause.__init__(self, dest)
            self.value = value
        def __str__(self):
            return "CONFIG_%s=%s" % (self.dest, 'y' if self.value else 'n')

        def process(self):
            self.dest.set_value(self.value, self)

    class DefaultClause(Clause):
        def __init__(self, dest, value, cond=None):
            KconfigData.Clause.__init__(self, dest)
            self.value = value
            self.cond = cond
            if not (self.cond is None):
                self.cond.add_edges_to(self.dest)
        def __str__(self):
            value = 'y' if self.value else 'n'
            if self.cond is None:
                return "config %s default %s" % (self.dest, value)
            else:
                return "config %s default %s if %s" % (self.dest, value, self.cond)

        def priority(self):
            # Defaults are processed just before leaving the variable
            return -1
        def process(self):
            if not self.dest.has_value() and \
                    (self.cond is None or self.cond.evaluate()):
                self.dest.set_value(self.value, self)

    class DependsOnClause(Clause):
        def __init__(self, dest, expr):
            KconfigData.Clause.__init__(self, dest)
            self.expr = expr
            self.expr.add_edges_to(self.dest)
        def __str__(self):
            return "config %s depends on %s" % (self.dest, self.expr)

        def process(self):
            if not self.expr.evaluate():
                self.dest.set_value(False, self)

    class SelectClause(Clause):
        def __init__(self, dest, cond):
            KconfigData.Clause.__init__(self, dest)
            self.cond = cond
            self.cond.add_edges_to(self.dest)
        def __str__(self):
            return "select %s if %s" % (self.dest, self.cond)

        def process(self):
            if self.cond.evaluate():
                self.dest.set_value(True, self)

    def __init__(self, value_mangler=defconfig):
        self.value_mangler = value_mangler
        self.previously_included = []
        self.incl_info = None
        self.defined_vars = set()
        self.referenced_vars = dict()
        self.clauses = list()

    # semantic analysis -------------

    def check_undefined(self):
        undef = False
        for i in self.referenced_vars:
            if not (i in self.defined_vars):
                print("undefined symbol %s" % (i), file=sys.stderr)
                undef = True
        return undef

    def compute_config(self):
        if self.check_undefined():
            raise KconfigDataError("there were undefined symbols")
            return None

        debug_print("Input:")
        for clause in self.clauses:
            debug_print(clause)

        debug_print("\nDependency graph:")
        for i in self.referenced_vars:
            debug_print(i, "->", [str(x) for x in self.referenced_vars[i].outgoing])

        # The reverse of the depth-first order is the topological sort
        dfo = dict()
        visited = set()
        debug_print("\n")
        def visit_fn(var):
            debug_print(var, "has DFS number", len(dfo))
            dfo[var] = len(dfo)

        for name, v in self.referenced_vars.items():
            self.do_default(v, False)
            v.dfs(visited, visit_fn)

        # Put higher DFS numbers and higher priorities first.  This
        # places the clauses in topological order and places defaults
        # after assignments and dependencies.
        self.clauses.sort(key=lambda x: (-dfo[x.dest], -x.priority()))

        debug_print("\nSorted clauses:")
        for clause in self.clauses:
            debug_print(clause)
            clause.process()

        debug_print("")
        values = dict()
        for name, v in self.referenced_vars.items():
            debug_print("Evaluating", name)
            values[name] = v.evaluate()

        return values

    # semantic actions -------------

    def do_declaration(self, var):
        if (var in self.defined_vars):
            raise KconfigDataError('variable "' + var + '" defined twice')

        self.defined_vars.add(var.name)

    # var is a string with the variable's name.
    def do_var(self, var):
        if (var in self.referenced_vars):
            return self.referenced_vars[var]

        var_obj = self.referenced_vars[var] = KconfigData.Var(var)
        return var_obj

    def do_assignment(self, var, val):
        self.clauses.append(KconfigData.AssignmentClause(var, val))

    def do_default(self, var, val, cond=None):
        val = self.value_mangler(val)
        self.clauses.append(KconfigData.DefaultClause(var, val, cond))

    def do_depends_on(self, var, expr):
        self.clauses.append(KconfigData.DependsOnClause(var, expr))

    def do_select(self, var, symbol, cond=None):
        cond = (cond & var) if cond is not None else var
        self.clauses.append(KconfigData.SelectClause(symbol, cond))

    def do_imply(self, var, symbol, cond=None):
        # "config X imply Y [if COND]" is the same as
        # "config Y default y if X [&& COND]"
        cond = (cond & var) if cond is not None else var
        self.do_default(symbol, True, cond)

# -------------------------------------------
# KconfigParser implements a recursive descent parser for (simplified)
# Kconfig syntax.
# -------------------------------------------

# tokens table
TOKENS = {}
TOK_NONE = -1
TOK_LPAREN = 0;   TOKENS[TOK_LPAREN] = '"("';
TOK_RPAREN = 1;   TOKENS[TOK_RPAREN] = '")"';
TOK_EQUAL = 2;    TOKENS[TOK_EQUAL] = '"="';
TOK_AND = 3;      TOKENS[TOK_AND] = '"&&"';
TOK_OR = 4;       TOKENS[TOK_OR] = '"||"';
TOK_NOT = 5;      TOKENS[TOK_NOT] = '"!"';
TOK_DEPENDS = 6;  TOKENS[TOK_DEPENDS] = '"depends"';
TOK_ON = 7;       TOKENS[TOK_ON] = '"on"';
TOK_SELECT = 8;   TOKENS[TOK_SELECT] = '"select"';
TOK_IMPLY = 9;    TOKENS[TOK_IMPLY] = '"imply"';
TOK_CONFIG = 10;  TOKENS[TOK_CONFIG] = '"config"';
TOK_DEFAULT = 11; TOKENS[TOK_DEFAULT] = '"default"';
TOK_Y = 12;       TOKENS[TOK_Y] = '"y"';
TOK_N = 13;       TOKENS[TOK_N] = '"n"';
TOK_SOURCE = 14;  TOKENS[TOK_SOURCE] = '"source"';
TOK_BOOL = 15;    TOKENS[TOK_BOOL] = '"bool"';
TOK_IF = 16;      TOKENS[TOK_IF] = '"if"';
TOK_ID = 17;      TOKENS[TOK_ID] = 'identifier';
TOK_EOF = 18;     TOKENS[TOK_EOF] = 'end of file';

class KconfigParserError(Exception):
    def __init__(self, parser, msg, tok=None):
        self.loc = parser.location()
        tok = tok or parser.tok
        if tok != TOK_NONE:
            location = TOKENS.get(tok, None) or ('"%s"' % tok)
            msg = '%s before %s' % (msg, location)
        self.msg = msg

    def __str__(self):
        return "%s: %s" % (self.loc, self.msg)

class KconfigParser:

    @classmethod
    def parse(self, fp, mode=None):
        data = KconfigData(mode or KconfigParser.defconfig)
        parser = KconfigParser(data)
        parser.parse_file(fp)
        return data

    def __init__(self, data):
        self.data = data

    def parse_file(self, fp):
        self.abs_fname = os.path.abspath(fp.name)
        self.fname = fp.name
        self.data.previously_included.append(self.abs_fname)
        self.src = fp.read()
        if self.src == '' or self.src[-1] != '\n':
            self.src += '\n'
        self.cursor = 0
        self.line = 1
        self.line_pos = 0
        self.get_token()
        self.parse_config()

    def do_assignment(self, var, val):
        if not var.startswith("CONFIG_"):
            raise Error('assigned variable should start with CONFIG_')
        var = self.data.do_var(var[7:])
        self.data.do_assignment(var, val)

    # file management -----

    def error_path(self):
        inf = self.data.incl_info
        res = ""
        while inf:
            res = ("In file included from %s:%d:\n" % (inf['file'],
                                                       inf['line'])) + res
            inf = inf['parent']
        return res

    def location(self):
        col = 1
        for ch in self.src[self.line_pos:self.pos]:
            if ch == '\t':
                col += 8 - ((col - 1) % 8)
            else:
                col += 1
        return '%s%s:%d:%d' %(self.error_path(), self.fname, self.line, col)

    def do_include(self, include):
        incl_abs_fname = os.path.join(os.path.dirname(self.abs_fname),
                                      include)
        # catch inclusion cycle
        inf = self.data.incl_info
        while inf:
            if incl_abs_fname == os.path.abspath(inf['file']):
                raise KconfigParserError(self, "Inclusion loop for %s"
                                    % include)
            inf = inf['parent']

        # skip multiple include of the same file
        if incl_abs_fname in self.data.previously_included:
            return
        try:
            fp = open(incl_abs_fname, 'rt', encoding='utf-8')
        except IOError as e:
            raise KconfigParserError(self,
                                '%s: %s' % (e.strerror, include))

        inf = self.data.incl_info
        self.data.incl_info = { 'file': self.fname, 'line': self.line,
                'parent': inf }
        KconfigParser(self.data).parse_file(fp)
        self.data.incl_info = inf

    # recursive descent parser -----

    # y_or_n: Y | N
    def parse_y_or_n(self):
        if self.tok == TOK_Y:
            self.get_token()
            return True
        if self.tok == TOK_N:
            self.get_token()
            return False
        raise KconfigParserError(self, 'Expected "y" or "n"')

    # var: ID
    def parse_var(self):
        if self.tok == TOK_ID:
            val = self.val
            self.get_token()
            return self.data.do_var(val)
        else:
            raise KconfigParserError(self, 'Expected identifier')

    # assignment_var: ID (starting with "CONFIG_")
    def parse_assignment_var(self):
        if self.tok == TOK_ID:
            val = self.val
            if not val.startswith("CONFIG_"):
                raise KconfigParserError(self,
                           'Expected identifier starting with "CONFIG_"', TOK_NONE)
            self.get_token()
            return self.data.do_var(val[7:])
        else:
            raise KconfigParserError(self, 'Expected identifier')

    # assignment: var EQUAL y_or_n
    def parse_assignment(self):
        var = self.parse_assignment_var()
        if self.tok != TOK_EQUAL:
            raise KconfigParserError(self, 'Expected "="')
        self.get_token()
        self.data.do_assignment(var, self.parse_y_or_n())

    # primary: NOT primary
    #       | LPAREN expr RPAREN
    #       | var
    def parse_primary(self):
        if self.tok == TOK_NOT:
            self.get_token()
            val = ~self.parse_primary()
        elif self.tok == TOK_LPAREN:
            self.get_token()
            val = self.parse_expr()
            if self.tok != TOK_RPAREN:
                raise KconfigParserError(self, 'Expected ")"')
            self.get_token()
        elif self.tok == TOK_ID:
            val = self.parse_var()
        else:
            raise KconfigParserError(self, 'Expected "!" or "(" or identifier')
        return val

    # disj: primary (OR primary)*
    def parse_disj(self):
        lhs = self.parse_primary()
        while self.tok == TOK_OR:
            self.get_token()
            lhs = lhs | self.parse_primary()
        return lhs

    # expr: disj (AND disj)*
    def parse_expr(self):
        lhs = self.parse_disj()
        while self.tok == TOK_AND:
            self.get_token()
            lhs = lhs & self.parse_disj()
        return lhs

    # condition: IF expr
    #       | empty
    def parse_condition(self):
        if self.tok == TOK_IF:
            self.get_token()
            return self.parse_expr()
        else:
            return None

    # property: DEFAULT y_or_n condition
    #       | DEPENDS ON expr
    #       | SELECT var condition
    #       | BOOL
    def parse_property(self, var):
        if self.tok == TOK_DEFAULT:
            self.get_token()
            val = self.parse_y_or_n()
            cond = self.parse_condition()
            self.data.do_default(var, val, cond)
        elif self.tok == TOK_DEPENDS:
            self.get_token()
            if self.tok != TOK_ON:
                raise KconfigParserError(self, 'Expected "on"')
            self.get_token()
            self.data.do_depends_on(var, self.parse_expr())
        elif self.tok == TOK_SELECT:
            self.get_token()
            symbol = self.parse_var()
            cond = self.parse_condition()
            self.data.do_select(var, symbol, cond)
        elif self.tok == TOK_IMPLY:
            self.get_token()
            symbol = self.parse_var()
            cond = self.parse_condition()
            self.data.do_imply(var, symbol, cond)
        elif self.tok == TOK_BOOL:
            self.get_token()
        else:
            raise KconfigParserError(self, 'Error in recursive descent?')

    # properties: properties property
    #       | /* empty */
    def parse_properties(self, var):
        had_default = False
        while self.tok == TOK_DEFAULT or self.tok == TOK_DEPENDS or \
              self.tok == TOK_SELECT or self.tok == TOK_BOOL or \
              self.tok == TOK_IMPLY:
            self.parse_property(var)

        # for nicer error message
        if self.tok != TOK_SOURCE and self.tok != TOK_CONFIG and \
           self.tok != TOK_ID and self.tok != TOK_EOF:
            raise KconfigParserError(self, 'expected "source", "config", identifier, '
                    + '"default", "depends on", "imply" or "select"')

    # declaration: config var properties
    def parse_declaration(self):
        if self.tok == TOK_CONFIG:
            self.get_token()
            var = self.parse_var()
            self.data.do_declaration(var)
            self.parse_properties(var)
        else:
            raise KconfigParserError(self, 'Error in recursive descent?')

    # clause: SOURCE
    #       | declaration
    #       | assignment
    def parse_clause(self):
        if self.tok == TOK_SOURCE:
            val = self.val
            self.get_token()
            self.do_include(val)
        elif self.tok == TOK_CONFIG:
            self.parse_declaration()
        elif self.tok == TOK_ID:
            self.parse_assignment()
        else:
            raise KconfigParserError(self, 'expected "source", "config" or identifier')

    # config: clause+ EOF
    def parse_config(self):
        while self.tok != TOK_EOF:
            self.parse_clause()
        return self.data

    # scanner -----

    def get_token(self):
        while True:
            self.tok = self.src[self.cursor]
            self.pos = self.cursor
            self.cursor += 1

            self.val = None
            self.tok = self.scan_token()
            if self.tok is not None:
                return

    def check_keyword(self, rest):
        if not self.src.startswith(rest, self.cursor):
            return False
        length = len(rest)
        if self.src[self.cursor + length].isalnum() or self.src[self.cursor + length] == '_':
            return False
        self.cursor += length
        return True

    def scan_token(self):
        if self.tok == '#':
            self.cursor = self.src.find('\n', self.cursor)
            return None
        elif self.tok == '=':
            return TOK_EQUAL
        elif self.tok == '(':
            return TOK_LPAREN
        elif self.tok == ')':
            return TOK_RPAREN
        elif self.tok == '&' and self.src[self.pos+1] == '&':
            self.cursor += 1
            return TOK_AND
        elif self.tok == '|' and self.src[self.pos+1] == '|':
            self.cursor += 1
            return TOK_OR
        elif self.tok == '!':
            return TOK_NOT
        elif self.tok == 'd' and self.check_keyword("epends"):
            return TOK_DEPENDS
        elif self.tok == 'o' and self.check_keyword("n"):
            return TOK_ON
        elif self.tok == 's' and self.check_keyword("elect"):
            return TOK_SELECT
        elif self.tok == 'i' and self.check_keyword("mply"):
            return TOK_IMPLY
        elif self.tok == 'c' and self.check_keyword("onfig"):
            return TOK_CONFIG
        elif self.tok == 'd' and self.check_keyword("efault"):
            return TOK_DEFAULT
        elif self.tok == 'b' and self.check_keyword("ool"):
            return TOK_BOOL
        elif self.tok == 'i' and self.check_keyword("f"):
            return TOK_IF
        elif self.tok == 'y' and self.check_keyword(""):
            return TOK_Y
        elif self.tok == 'n' and self.check_keyword(""):
            return TOK_N
        elif (self.tok == 's' and self.check_keyword("ource")) or \
              self.tok == 'i' and self.check_keyword("nclude"):
            # source FILENAME
            # include FILENAME
            while self.src[self.cursor].isspace():
                self.cursor += 1
            start = self.cursor
            self.cursor = self.src.find('\n', self.cursor)
            self.val = self.src[start:self.cursor]
            return TOK_SOURCE
        elif self.tok.isalnum():
            # identifier
            while self.src[self.cursor].isalnum() or self.src[self.cursor] == '_':
                self.cursor += 1
            self.val = self.src[self.pos:self.cursor]
            return TOK_ID
        elif self.tok == '\n':
            if self.cursor == len(self.src):
                return TOK_EOF
            self.line += 1
            self.line_pos = self.cursor
        elif not self.tok.isspace():
            raise KconfigParserError(self, 'invalid input')

        return None

if __name__ == '__main__':
    argv = sys.argv
    mode = defconfig
    if len(sys.argv) > 1:
        if argv[1] == '--defconfig':
            del argv[1]
        elif argv[1] == '--randconfig':
            random.seed()
            mode = randconfig
            del argv[1]
        elif argv[1] == '--allyesconfig':
            mode = allyesconfig
            del argv[1]
        elif argv[1] == '--allnoconfig':
            mode = allnoconfig
            del argv[1]

    if len(argv) == 1:
        print ("%s: at least one argument is required" % argv[0], file=sys.stderr)
        sys.exit(1)

    if argv[1].startswith('-'):
        print ("%s: invalid option %s" % (argv[0], argv[1]), file=sys.stderr)
        sys.exit(1)

    data = KconfigData(mode)
    parser = KconfigParser(data)
    external_vars = set()
    for arg in argv[3:]:
        m = re.match(r'^(CONFIG_[A-Z0-9_]+)=([yn]?)$', arg)
        if m is not None:
            name, value = m.groups()
            parser.do_assignment(name, value == 'y')
            external_vars.add(name[7:])
        else:
            fp = open(arg, 'rt', encoding='utf-8')
            parser.parse_file(fp)
            fp.close()

    config = data.compute_config()
    for key in sorted(config.keys()):
        if key not in external_vars and config[key]:
            print ('CONFIG_%s=y' % key)

    deps = open(argv[2], 'wt', encoding='utf-8')
    for fname in data.previously_included:
        print ('%s: %s' % (argv[1], fname), file=deps)
    deps.close()
