#
# Small helper library to manipulate Kconfig files
#

import os, re

src_line = re.compile(r'^\s*source\s+"?(?P<src>[^\s"]*)"?\s*$')
tri_line = re.compile(r'^(?P<spc>\s+)tristate')
bool_line = re.compile(r'^(?P<spc>\s+)bool')
cfg_line = re.compile(r'^(config|menuconfig)\s+(?P<sym>[^\s]*)')
sel_line = re.compile(r'^(?P<spc>\s+)select\s+(?P<sym>[^\s]*)\s*$')
backport_line = re.compile(r'^\s+#(?P<key>[ch]-file|module-name)\s*(?P<name>.*)')

class ConfigTree(object):
    def __init__(self, rootfile):
        self.basedir = os.path.dirname(rootfile)
        self.rootfile = os.path.basename(rootfile)

    def _walk(self, f):
        yield f
        for l in open(os.path.join(self.basedir, f), 'r'):
            m = src_line.match(l)
            if m and os.path.exists(os.path.join(self.basedir, m.group('src'))):
                for i in self._walk(m.group('src')):
                    yield i

    def _prune_sources(self, f, ignore):
        for nf in self._walk(f):
            out = ''
            for l in open(os.path.join(self.basedir, nf), 'r'):
                m = src_line.match(l)
                if not m:
                    out += l
                    continue
                src = m.group('src')
                if src in ignore or os.path.exists(os.path.join(self.basedir, src)):
                    out += l
                else:
                    out += '#' + l
            outf = open(os.path.join(self.basedir, nf), 'w')
            outf.write(out)
            outf.close()

    def prune_sources(self, ignore=[]):
        self._prune_sources(self.rootfile, ignore)

    def force_tristate_modular(self):
        for nf in self._walk(self.rootfile):
            out = ''
            for l in open(os.path.join(self.basedir, nf), 'r'):
                m = tri_line.match(l)
                out += l
                if m:
                    out += m.group('spc') + "depends on m\n"
            outf = open(os.path.join(self.basedir, nf), 'w')
            outf.write(out)
            outf.close()

    def symbols(self):
        syms = []
        for nf in self._walk(self.rootfile):
            for l in open(os.path.join(self.basedir, nf), 'r'):
                m = cfg_line.match(l)
                if m:
                    syms.append(m.group('sym'))
        return syms

    def all_selects(self):
        result = []
        for nf in self._walk(self.rootfile):
            for l in open(os.path.join(self.basedir, nf), 'r'):
                m = sel_line.match(l)
                if m:
                    result.append(m.group('sym'))
        return result

    def modify_selects(self):
        syms = self.symbols()
        for nf in self._walk(self.rootfile):
            out = ''
            for l in open(os.path.join(self.basedir, nf), 'r'):
                m = sel_line.match(l)
                if m and not m.group('sym') in syms:
                    if 'BACKPORT_' + m.group('sym') in syms:
                        out += m.group('spc') + "select BACKPORT_" + m.group('sym') + '\n'
                    else:
                        out += m.group('spc') + "depends on " + m.group('sym') + '\n'
                else:
                    out += l
            outf = open(os.path.join(self.basedir, nf), 'w')
            outf.write(out)
            outf.close()

    def disable_symbols(self, syms):
        for nf in self._walk(self.rootfile):
            out = ''
            for l in open(os.path.join(self.basedir, nf), 'r'):
                m = cfg_line.match(l)
                out += l
                if m and m.group('sym') in syms:
                    out += "\tdepends on n\n"
            outf = open(os.path.join(self.basedir, nf), 'w')
            outf.write(out)
            outf.close()

    def add_dependencies(self, deps):
        for nf in self._walk(self.rootfile):
            out = ''
            for l in open(os.path.join(self.basedir, nf), 'r'):
                m = cfg_line.match(l)
                out += l
                if m:
                    for dep in deps.get(m.group('sym'), []):
                        out += "\tdepends on %s\n" % dep
            outf = open(os.path.join(self.basedir, nf), 'w')
            outf.write(out)
            outf.close()

def get_backport_info(filename):
    """
    Return a dictionary of

    CONFIG_SYMBOL => (type, C-files, H-files)

    where type is 'bool' or 'tristate' and the C-files/H-files are lists
    """
    f = open(filename, 'r')
    result = {}
    conf = None
    module_name = None

    # trick to always have an empty line last
    def append_empty(f):
        for l in f:
            yield l
        yield ''

    for line in append_empty(f):
        m = cfg_line.match(line)
        if not line.strip() or m:
            if conf and conf_type and (c_files or h_files):
                result[conf] = (conf_type, module_name, c_files, h_files)
            conf = None
            conf_type = None
            module_name = None
            c_files = []
            h_files = []
            if m:
                conf = m.group('sym')
            continue
        if not conf:
            continue
        m = tri_line.match(line)
        if m:
            conf_type = 'tristate'
            continue
        m = bool_line.match(line)
        if m:
            conf_type = 'bool'
            continue
        m = backport_line.match(line)
        if m:
            if m.group('key') == 'c-file':
                c_files.append(m.group('name'))
            elif m.group('key') == 'h-file':
                h_files.append(m.group('name'))
            elif m.group('key') == 'module-name':
                module_name = m.group('name')
    return result
