#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only

"""Find Kconfig symbols that are referenced but not defined."""

# (c) 2014-2017 Valentin Rothberg <valentinrothberg@gmail.com>
# (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de>
#


import argparse
import difflib
import os
import re
import signal
import subprocess
import sys
from multiprocessing import Pool, cpu_count


# regex expressions
OPERATORS = r"&|\(|\)|\||\!"
SYMBOL = r"(?:\w*[A-Z0-9]\w*){2,}"
DEF = r"^\s*(?:menu){,1}config\s+(" + SYMBOL + r")\s*"
EXPR = r"(?:" + OPERATORS + r"|\s|" + SYMBOL + r")+"
DEFAULT = r"default\s+.*?(?:if\s.+){,1}"
STMT = r"^\s*(?:if|select|imply|depends\s+on|(?:" + DEFAULT + r"))\s+" + EXPR
SOURCE_SYMBOL = r"(?:\W|\b)+[D]{,1}CONFIG_(" + SYMBOL + r")"

# regex objects
REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$")
REGEX_SYMBOL = re.compile(r'(?!\B)' + SYMBOL + r'(?!\B)')
REGEX_SOURCE_SYMBOL = re.compile(SOURCE_SYMBOL)
REGEX_KCONFIG_DEF = re.compile(DEF)
REGEX_KCONFIG_EXPR = re.compile(EXPR)
REGEX_KCONFIG_STMT = re.compile(STMT)
REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$")
REGEX_FILTER_SYMBOLS = re.compile(r"[A-Za-z0-9]$")
REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+")
REGEX_QUOTES = re.compile("(\"(.*?)\")")


def parse_options():
    """The user interface of this module."""
    usage = "Run this tool to detect Kconfig symbols that are referenced but " \
            "not defined in Kconfig.  If no option is specified, "             \
            "checkkconfigsymbols defaults to check your current tree.  "       \
            "Please note that specifying commits will 'git reset --hard\' "    \
            "your current tree!  You may save uncommitted changes to avoid "   \
            "losing data."

    parser = argparse.ArgumentParser(description=usage)

    parser.add_argument('-c', '--commit', dest='commit', action='store',
                        default="",
                        help="check if the specified commit (hash) introduces "
                             "undefined Kconfig symbols")

    parser.add_argument('-d', '--diff', dest='diff', action='store',
                        default="",
                        help="diff undefined symbols between two commits "
                             "(e.g., -d commmit1..commit2)")

    parser.add_argument('-f', '--find', dest='find', action='store_true',
                        default=False,
                        help="find and show commits that may cause symbols to be "
                             "missing (required to run with --diff)")

    parser.add_argument('-i', '--ignore', dest='ignore', action='store',
                        default="",
                        help="ignore files matching this Python regex "
                             "(e.g., -i '.*defconfig')")

    parser.add_argument('-s', '--sim', dest='sim', action='store', default="",
                        help="print a list of max. 10 string-similar symbols")

    parser.add_argument('--force', dest='force', action='store_true',
                        default=False,
                        help="reset current Git tree even when it's dirty")

    parser.add_argument('--no-color', dest='color', action='store_false',
                        default=True,
                        help="don't print colored output (default when not "
                             "outputting to a terminal)")

    args = parser.parse_args()

    if args.commit and args.diff:
        sys.exit("Please specify only one option at once.")

    if args.diff and not re.match(r"^[\w\-\.\^]+\.\.[\w\-\.\^]+$", args.diff):
        sys.exit("Please specify valid input in the following format: "
                 "\'commit1..commit2\'")

    if args.commit or args.diff:
        if not args.force and tree_is_dirty():
            sys.exit("The current Git tree is dirty (see 'git status').  "
                     "Running this script may\ndelete important data since it "
                     "calls 'git reset --hard' for some performance\nreasons. "
                     " Please run this script in a clean Git tree or pass "
                     "'--force' if you\nwant to ignore this warning and "
                     "continue.")

    if args.commit:
        args.find = False

    if args.ignore:
        try:
            re.match(args.ignore, "this/is/just/a/test.c")
        except:
            sys.exit("Please specify a valid Python regex.")

    return args


def main():
    """Main function of this module."""
    args = parse_options()

    global COLOR
    COLOR = args.color and sys.stdout.isatty()

    if args.sim and not args.commit and not args.diff:
        sims = find_sims(args.sim, args.ignore)
        if sims:
            print("%s: %s" % (yel("Similar symbols"), ', '.join(sims)))
        else:
            print("%s: no similar symbols found" % yel("Similar symbols"))
        sys.exit(0)

    # dictionary of (un)defined symbols
    defined = {}
    undefined = {}

    if args.commit or args.diff:
        head = get_head()

        # get commit range
        commit_a = None
        commit_b = None
        if args.commit:
            commit_a = args.commit + "~"
            commit_b = args.commit
        elif args.diff:
            split = args.diff.split("..")
            commit_a = split[0]
            commit_b = split[1]
            undefined_a = {}
            undefined_b = {}

        # get undefined items before the commit
        reset(commit_a)
        undefined_a, _ = check_symbols(args.ignore)

        # get undefined items for the commit
        reset(commit_b)
        undefined_b, defined = check_symbols(args.ignore)

        # report cases that are present for the commit but not before
        for symbol in sorted(undefined_b):
            # symbol has not been undefined before
            if symbol not in undefined_a:
                files = sorted(undefined_b.get(symbol))
                undefined[symbol] = files
            # check if there are new files that reference the undefined symbol
            else:
                files = sorted(undefined_b.get(symbol) -
                               undefined_a.get(symbol))
                if files:
                    undefined[symbol] = files

        # reset to head
        reset(head)

    # default to check the entire tree
    else:
        undefined, defined = check_symbols(args.ignore)

    # now print the output
    for symbol in sorted(undefined):
        print(red(symbol))

        files = sorted(undefined.get(symbol))
        print("%s: %s" % (yel("Referencing files"), ", ".join(files)))

        sims = find_sims(symbol, args.ignore, defined)
        sims_out = yel("Similar symbols")
        if sims:
            print("%s: %s" % (sims_out, ', '.join(sims)))
        else:
            print("%s: %s" % (sims_out, "no similar symbols found"))

        if args.find:
            print("%s:" % yel("Commits changing symbol"))
            commits = find_commits(symbol, args.diff)
            if commits:
                for commit in commits:
                    commit = commit.split(" ", 1)
                    print("\t- %s (\"%s\")" % (yel(commit[0]), commit[1]))
            else:
                print("\t- no commit found")
        print()  # new line


def reset(commit):
    """Reset current git tree to %commit."""
    execute(["git", "reset", "--hard", commit])


def yel(string):
    """
    Color %string yellow.
    """
    return "\033[33m%s\033[0m" % string if COLOR else string


def red(string):
    """
    Color %string red.
    """
    return "\033[31m%s\033[0m" % string if COLOR else string


def execute(cmd):
    """Execute %cmd and return stdout.  Exit in case of error."""
    try:
        stdout = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
        stdout = stdout.decode(errors='replace')
    except subprocess.CalledProcessError as fail:
        exit(fail)
    return stdout


def find_commits(symbol, diff):
    """Find commits changing %symbol in the given range of %diff."""
    commits = execute(["git", "log", "--pretty=oneline",
                       "--abbrev-commit", "-G",
                       symbol, diff])
    return [x for x in commits.split("\n") if x]


def tree_is_dirty():
    """Return true if the current working tree is dirty (i.e., if any file has
    been added, deleted, modified, renamed or copied but not committed)."""
    stdout = execute(["git", "status", "--porcelain"])
    for line in stdout:
        if re.findall(r"[URMADC]{1}", line[:2]):
            return True
    return False


def get_head():
    """Return commit hash of current HEAD."""
    stdout = execute(["git", "rev-parse", "HEAD"])
    return stdout.strip('\n')


def partition(lst, size):
    """Partition list @lst into eveni-sized lists of size @size."""
    return [lst[i::size] for i in range(size)]


def init_worker():
    """Set signal handler to ignore SIGINT."""
    signal.signal(signal.SIGINT, signal.SIG_IGN)


def find_sims(symbol, ignore, defined=[]):
    """Return a list of max. ten Kconfig symbols that are string-similar to
    @symbol."""
    if defined:
        return difflib.get_close_matches(symbol, set(defined), 10)

    pool = Pool(cpu_count(), init_worker)
    kfiles = []
    for gitfile in get_files():
        if REGEX_FILE_KCONFIG.match(gitfile):
            kfiles.append(gitfile)

    arglist = []
    for part in partition(kfiles, cpu_count()):
        arglist.append((part, ignore))

    for res in pool.map(parse_kconfig_files, arglist):
        defined.extend(res[0])

    return difflib.get_close_matches(symbol, set(defined), 10)


def get_files():
    """Return a list of all files in the current git directory."""
    # use 'git ls-files' to get the worklist
    stdout = execute(["git", "ls-files"])
    if len(stdout) > 0 and stdout[-1] == "\n":
        stdout = stdout[:-1]

    files = []
    for gitfile in stdout.rsplit("\n"):
        if ".git" in gitfile or "ChangeLog" in gitfile or      \
                ".log" in gitfile or os.path.isdir(gitfile) or \
                gitfile.startswith("tools/"):
            continue
        files.append(gitfile)
    return files


def check_symbols(ignore):
    """Find undefined Kconfig symbols and return a dict with the symbol as key
    and a list of referencing files as value.  Files matching %ignore are not
    checked for undefined symbols."""
    pool = Pool(cpu_count(), init_worker)
    try:
        return check_symbols_helper(pool, ignore)
    except KeyboardInterrupt:
        pool.terminate()
        pool.join()
        sys.exit(1)


def check_symbols_helper(pool, ignore):
    """Helper method for check_symbols().  Used to catch keyboard interrupts in
    check_symbols() in order to properly terminate running worker processes."""
    source_files = []
    kconfig_files = []
    defined_symbols = []
    referenced_symbols = dict()  # {file: [symbols]}

    for gitfile in get_files():
        if REGEX_FILE_KCONFIG.match(gitfile):
            kconfig_files.append(gitfile)
        else:
            if ignore and not re.match(ignore, gitfile):
                continue
            # add source files that do not match the ignore pattern
            source_files.append(gitfile)

    # parse source files
    arglist = partition(source_files, cpu_count())
    for res in pool.map(parse_source_files, arglist):
        referenced_symbols.update(res)

    # parse kconfig files
    arglist = []
    for part in partition(kconfig_files, cpu_count()):
        arglist.append((part, ignore))
    for res in pool.map(parse_kconfig_files, arglist):
        defined_symbols.extend(res[0])
        referenced_symbols.update(res[1])
    defined_symbols = set(defined_symbols)

    # inverse mapping of referenced_symbols to dict(symbol: [files])
    inv_map = dict()
    for _file, symbols in referenced_symbols.items():
        for symbol in symbols:
            inv_map[symbol] = inv_map.get(symbol, set())
            inv_map[symbol].add(_file)
    referenced_symbols = inv_map

    undefined = {}  # {symbol: [files]}
    for symbol in sorted(referenced_symbols):
        # filter some false positives
        if symbol == "FOO" or symbol == "BAR" or \
                symbol == "FOO_BAR" or symbol == "XXX":
            continue
        if symbol not in defined_symbols:
            if symbol.endswith("_MODULE"):
                # avoid false positives for kernel modules
                if symbol[:-len("_MODULE")] in defined_symbols:
                    continue
            undefined[symbol] = referenced_symbols.get(symbol)
    return undefined, defined_symbols


def parse_source_files(source_files):
    """Parse each source file in @source_files and return dictionary with source
    files as keys and lists of references Kconfig symbols as values."""
    referenced_symbols = dict()
    for sfile in source_files:
        referenced_symbols[sfile] = parse_source_file(sfile)
    return referenced_symbols


def parse_source_file(sfile):
    """Parse @sfile and return a list of referenced Kconfig symbols."""
    lines = []
    references = []

    if not os.path.exists(sfile):
        return references

    with open(sfile, "r", encoding='utf-8', errors='replace') as stream:
        lines = stream.readlines()

    for line in lines:
        if "CONFIG_" not in line:
            continue
        symbols = REGEX_SOURCE_SYMBOL.findall(line)
        for symbol in symbols:
            if not REGEX_FILTER_SYMBOLS.search(symbol):
                continue
            references.append(symbol)

    return references


def get_symbols_in_line(line):
    """Return mentioned Kconfig symbols in @line."""
    return REGEX_SYMBOL.findall(line)


def parse_kconfig_files(args):
    """Parse kconfig files and return tuple of defined and references Kconfig
    symbols.  Note, @args is a tuple of a list of files and the @ignore
    pattern."""
    kconfig_files = args[0]
    ignore = args[1]
    defined_symbols = []
    referenced_symbols = dict()

    for kfile in kconfig_files:
        defined, references = parse_kconfig_file(kfile)
        defined_symbols.extend(defined)
        if ignore and re.match(ignore, kfile):
            # do not collect references for files that match the ignore pattern
            continue
        referenced_symbols[kfile] = references
    return (defined_symbols, referenced_symbols)


def parse_kconfig_file(kfile):
    """Parse @kfile and update symbol definitions and references."""
    lines = []
    defined = []
    references = []
    skip = False

    if not os.path.exists(kfile):
        return defined, references

    with open(kfile, "r", encoding='utf-8', errors='replace') as stream:
        lines = stream.readlines()

    for i in range(len(lines)):
        line = lines[i]
        line = line.strip('\n')
        line = line.split("#")[0]  # ignore comments

        if REGEX_KCONFIG_DEF.match(line):
            symbol_def = REGEX_KCONFIG_DEF.findall(line)
            defined.append(symbol_def[0])
            skip = False
        elif REGEX_KCONFIG_HELP.match(line):
            skip = True
        elif skip:
            # ignore content of help messages
            pass
        elif REGEX_KCONFIG_STMT.match(line):
            line = REGEX_QUOTES.sub("", line)
            symbols = get_symbols_in_line(line)
            # multi-line statements
            while line.endswith("\\"):
                i += 1
                line = lines[i]
                line = line.strip('\n')
                symbols.extend(get_symbols_in_line(line))
            for symbol in set(symbols):
                if REGEX_NUMERIC.match(symbol):
                    # ignore numeric values
                    continue
                references.append(symbol)

    return defined, references


if __name__ == "__main__":
    main()
