#!/usr/bin/env python3

# Copyright (c) 2019 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

"""
Linter for the Zephyr Kconfig files. Pass --help to see
available checks. By default, all checks are enabled.

Some of the checks rely on heuristics and can get tripped up
by things like preprocessor magic, so manual checking is
still needed. 'git grep' is handy.

Requires west, because the checks need to see Kconfig files
and source code from modules.
"""

import argparse
import os
import re
import shlex
import subprocess
import sys
import tempfile

TOP_DIR = os.path.join(os.path.dirname(__file__), "..", "..")

sys.path.insert(0, os.path.join(TOP_DIR, "scripts", "kconfig"))
import kconfiglib


def main():
    init_kconfig()

    args = parse_args()
    if args.checks:
        checks = args.checks
    else:
        # Run all checks if no checks were specified
        checks = (check_always_n,
                  check_unused,
                  check_pointless_menuconfigs,
                  check_defconfig_only_definition,
                  check_missing_config_prefix)

    first = True
    for check in checks:
        if not first:
            print()
        first = False
        check()


def parse_args():
    # args.checks is set to a list of check functions to run

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawTextHelpFormatter,
        description=__doc__, allow_abbrev=False)

    parser.add_argument(
        "-n", "--check-always-n",
        action="append_const", dest="checks", const=check_always_n,
        help="""\
List symbols that can never be anything but n/empty. These
are detected as symbols with no prompt or defaults that
aren't selected or implied.
""")

    parser.add_argument(
        "-u", "--check-unused",
        action="append_const", dest="checks", const=check_unused,
        help="""\
List symbols that might be unused.

Heuristic:

 - Isn't referenced in Kconfig
 - Isn't referenced as CONFIG_<NAME> outside Kconfig
   (besides possibly as CONFIG_<NAME>=<VALUE>)
 - Isn't selecting/implying other symbols
 - Isn't a choice symbol

C preprocessor magic can trip up this check.""")

    parser.add_argument(
        "-m", "--check-pointless-menuconfigs",
        action="append_const", dest="checks", const=check_pointless_menuconfigs,
        help="""\
List symbols defined with 'menuconfig' where the menu is
empty due to the symbol not being followed by stuff that
depends on it""")

    parser.add_argument(
        "-d", "--check-defconfig-only-definition",
        action="append_const", dest="checks", const=check_defconfig_only_definition,
        help="""\
List symbols that are only defined in Kconfig.defconfig
files. A common base definition should probably be added
somewhere for such symbols, and the type declaration ('int',
'hex', etc.) removed from Kconfig.defconfig.""")

    parser.add_argument(
        "-p", "--check-missing-config-prefix",
        action="append_const", dest="checks", const=check_missing_config_prefix,
        help="""\
Look for references like

    #if MACRO
    #if(n)def MACRO
    defined(MACRO)
    IS_ENABLED(MACRO)

where MACRO is the name of a defined Kconfig symbol but
doesn't have a CONFIG_ prefix. Could be a typo.

Macros that are #define'd somewhere are not flagged.""")

    return parser.parse_args()


def check_always_n():
    print_header("Symbols that can't be anything but n/empty")
    for sym in kconf.unique_defined_syms:
        if not has_prompt(sym) and not is_selected_or_implied(sym) and \
           not has_defaults(sym):
            print(name_and_locs(sym))


def check_unused():
    print_header("Symbols that look unused")
    referenced = referenced_sym_names()
    for sym in kconf.unique_defined_syms:
        if not is_selecting_or_implying(sym) and not sym.choice and \
           sym.name not in referenced:
            print(name_and_locs(sym))


def check_pointless_menuconfigs():
    print_header("menuconfig symbols with empty menus")
    for node in kconf.node_iter():
        if node.is_menuconfig and not node.list and \
           isinstance(node.item, kconfiglib.Symbol):
            print("{0.item.name:40} {0.filename}:{0.linenr}".format(node))


def check_defconfig_only_definition():
    print_header("Symbols only defined in Kconfig.defconfig files")
    for sym in kconf.unique_defined_syms:
        if all("defconfig" in node.filename for node in sym.nodes):
            print(name_and_locs(sym))


def check_missing_config_prefix():
    print_header("Symbol references that might be missing a CONFIG_ prefix")

    # Paths to modules
    modpaths = run(("west", "list", "-f{abspath}")).splitlines()

    # Gather #define'd macros that might overlap with symbol names, so that
    # they don't trigger false positives
    defined = set()
    for modpath in modpaths:
        regex = r"#\s*define\s+([A-Z0-9_]+)\b"
        defines = run(("git", "grep", "--extended-regexp", regex),
                      cwd=modpath, check=False)
        # Could pass --only-matching to git grep as well, but it was added
        # pretty recently (2018)
        defined.update(re.findall(regex, defines))

    # Filter out symbols whose names are #define'd too. Preserve definition
    # order to make the output consistent.
    syms = [sym for sym in kconf.unique_defined_syms
            if sym.name not in defined]

    # grep for symbol references in #ifdef/defined() that are missing a CONFIG_
    # prefix. Work around an "argument list too long" error from 'git grep' by
    # checking symbols in batches.
    for batch in split_list(syms, 200):
        # grep for '#if((n)def) <symbol>', 'defined(<symbol>', and
        # 'IS_ENABLED(<symbol>', with a missing CONFIG_ prefix
        regex = r"(?:#\s*if(?:n?def)\s+|\bdefined\s*\(\s*|IS_ENABLED\(\s*)(?:" + \
                "|".join(sym.name for sym in batch) + r")\b"
        cmd = ("git", "grep", "--line-number", "-I", "--perl-regexp", regex)

        for modpath in modpaths:
            print(run(cmd, cwd=modpath, check=False), end="")


def split_list(lst, batch_size):
    # check_missing_config_prefix() helper generator that splits a list into
    # equal-sized batches (possibly with a shorter batch at the end)

    for i in range(0, len(lst), batch_size):
        yield lst[i:i + batch_size]


def print_header(s):
    print(s + "\n" + len(s)*"=")


def init_kconfig():
    global kconf

    os.environ.update(
        srctree=TOP_DIR,
        CMAKE_BINARY_DIR=modules_file_dir(),
        KCONFIG_DOC_MODE="1",
        ZEPHYR_BASE=TOP_DIR,
        SOC_DIR="soc",
        ARCH_DIR="arch",
        BOARD_DIR="boards/*/*",
        ARCH="*")

    kconf = kconfiglib.Kconfig(suppress_traceback=True)


def modules_file_dir():
    # Creates Kconfig.modules in a temporary directory and returns the path to
    # the directory. Kconfig.modules brings in Kconfig files from modules.

    tmpdir = tempfile.mkdtemp()
    run((os.path.join("scripts", "zephyr_module.py"),
         "--kconfig-out", os.path.join(tmpdir, "Kconfig.modules")))
    return tmpdir


def referenced_sym_names():
    # Returns the names of all symbols referenced inside and outside the
    # Kconfig files (that we can detect), without any "CONFIG_" prefix

    return referenced_in_kconfig() | referenced_outside_kconfig()


def referenced_in_kconfig():
    # Returns the names of all symbols referenced inside the Kconfig files

    return {ref.name
            for node in kconf.node_iter()
                for ref in node.referenced
                    if isinstance(ref, kconfiglib.Symbol)}


def referenced_outside_kconfig():
    # Returns the names of all symbols referenced outside the Kconfig files

    regex = r"\bCONFIG_[A-Z0-9_]+\b"

    res = set()

    # 'git grep' all modules
    for modpath in run(("west", "list", "-f{abspath}")).splitlines():
        for line in run(("git", "grep", "-h", "-I", "--extended-regexp", regex),
                        cwd=modpath).splitlines():
            # Don't record lines starting with "CONFIG_FOO=" or "# CONFIG_FOO="
            # as references, so that symbols that are only assigned in .config
            # files are not included
            if re.match(r"[\s#]*CONFIG_[A-Z0-9_]+=.*", line):
                continue

            # Could pass --only-matching to git grep as well, but it was added
            # pretty recently (2018)
            for match in re.findall(regex, line):
                res.add(match[7:])  # Strip "CONFIG_"

    return res


def has_prompt(sym):
    return any(node.prompt for node in sym.nodes)


def is_selected_or_implied(sym):
    return sym.rev_dep is not kconf.n or sym.weak_rev_dep is not kconf.n


def has_defaults(sym):
    return bool(sym.defaults)


def is_selecting_or_implying(sym):
    return sym.selects or sym.implies


def name_and_locs(sym):
    # Returns a string with the name and definition location(s) for 'sym'

    return "{:40} {}".format(
        sym.name,
        ", ".join("{0.filename}:{0.linenr}".format(node) for node in sym.nodes))


def run(cmd, cwd=TOP_DIR, check=True):
    # Runs 'cmd' with subprocess, returning the decoded stdout output. 'cwd' is
    # the working directory. It defaults to the top-level Zephyr directory.
    # Exits with an error if the command exits with a non-zero return code if
    # 'check' is True.

    cmd_s = " ".join(shlex.quote(word) for word in cmd)

    try:
        process = subprocess.Popen(
            cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
    except OSError as e:
        err("Failed to run '{}': {}".format(cmd_s, e))

    stdout, stderr = process.communicate()
    # errors="ignore" temporarily works around
    # https://github.com/zephyrproject-rtos/esp-idf/pull/2
    stdout = stdout.decode("utf-8", errors="ignore")
    stderr = stderr.decode("utf-8")
    if check and process.returncode:
        err("""\
'{}' exited with status {}.

===stdout===
{}
===stderr===
{}""".format(cmd_s, process.returncode, stdout, stderr))

    if stderr:
        warn("'{}' wrote to stderr:\n{}".format(cmd_s, stderr))

    return stdout


def err(msg):
    sys.exit(executable() + "error: " + msg)


def warn(msg):
    print(executable() + "warning: " + msg, file=sys.stderr)


def executable():
    cmd = sys.argv[0]  # Empty string if missing
    return cmd + ": " if cmd else ""


if __name__ == "__main__":
    main()
