#!/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",
        KCONFIG_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()
