#!/usr/bin/env python3
# See utils/checkpackagelib/readme.txt before editing this file.

import argparse
import inspect
import magic
import os
import re
import sys

import checkpackagelib.base
import checkpackagelib.lib_config
import checkpackagelib.lib_defconfig
import checkpackagelib.lib_hash
import checkpackagelib.lib_ignore
import checkpackagelib.lib_mk
import checkpackagelib.lib_patch
import checkpackagelib.lib_python
import checkpackagelib.lib_shellscript
import checkpackagelib.lib_sysv

VERBOSE_LEVEL_TO_SHOW_IGNORED_FILES = 3
flags = None  # Command line arguments.

# There are two Python packages called 'magic':
#   https://pypi.org/project/file-magic/
#   https://pypi.org/project/python-magic/
# Both allow to return a MIME file type, but with a slightly different
# interface. Detect which one of the two we have based on one of the
# attributes.
if hasattr(magic, 'FileMagic'):
    # https://pypi.org/project/file-magic/
    def get_filetype(fname):
        return magic.detect_from_filename(fname).mime_type
else:
    # https://pypi.org/project/python-magic/
    def get_filetype(fname):
        return magic.from_file(fname, mime=True)


def get_ignored_parsers_per_file(intree_only, ignore_filename):
    ignored = dict()
    entry_base_dir = ''

    if not ignore_filename:
        return ignored

    filename = os.path.abspath(ignore_filename)
    entry_base_dir = os.path.join(os.path.dirname(filename))

    with open(filename, "r") as f:
        for line in f.readlines():
            filename, warnings_str = line.split(' ', 1)
            warnings = warnings_str.split()
            ignored[os.path.join(entry_base_dir, filename)] = warnings
    return ignored


def parse_args():
    parser = argparse.ArgumentParser()

    # Do not use argparse.FileType("r") here because only files with known
    # format will be open based on the filename.
    parser.add_argument("files", metavar="F", type=str, nargs="*",
                        help="list of files")

    parser.add_argument("--br2-external", "-b", dest='intree_only', action="store_false",
                        help="do not apply the pathname filters used for intree files")
    parser.add_argument("--ignore-list", dest='ignore_filename', action="store",
                        help='override the default list of ignored warnings')

    parser.add_argument("--manual-url", action="store",
                        default="https://nightly.buildroot.org/",
                        help="default: %(default)s")
    parser.add_argument("--verbose", "-v", action="count", default=0)
    parser.add_argument("--quiet", "-q", action="count", default=0)

    # Now the debug options in the order they are processed.
    parser.add_argument("--include-only", dest="include_list", action="append",
                        help="run only the specified functions (debug)")
    parser.add_argument("--exclude", dest="exclude_list", action="append",
                        help="do not run the specified functions (debug)")
    parser.add_argument("--dry-run", action="store_true", help="print the "
                        "functions that would be called for each file (debug)")
    parser.add_argument("--failed-only", action="store_true", help="print only"
                        " the name of the functions that failed (debug)")

    parser.add_argument("--test-suite", action="store_true", help="Run the"
                        " test-suite")

    flags = parser.parse_args()

    flags.ignore_list = get_ignored_parsers_per_file(flags.intree_only, flags.ignore_filename)

    if flags.failed_only:
        flags.dry_run = False
        flags.verbose = -1

    return flags


def get_lib_from_filetype(fname):
    if not os.path.isfile(fname):
        return None
    filetype = get_filetype(fname)
    if filetype == "text/x-shellscript":
        return checkpackagelib.lib_shellscript
    if filetype in ["text/x-python", "text/x-script.python"]:
        return checkpackagelib.lib_python
    return None


CONFIG_IN_FILENAME = re.compile(r"Config\.\S*$")
DO_CHECK_INTREE = re.compile(r"|".join([
    r".checkpackageignore",
    r"Config.in",
    r"arch/",
    r"board/",
    r"boot/",
    r"configs/",
    r"fs/",
    r"linux/",
    r"package/",
    r"support/",
    r"system/",
    r"toolchain/",
    r"utils/",
    ]))
DO_NOT_CHECK_INTREE = re.compile(r"|".join([
    r"boot/barebox/barebox\.mk$",
    r"fs/common\.mk$",
    r"package/alchemy/atom.mk.in$",
    r"package/doc-asciidoc\.mk$",
    r"package/pkg-\S*\.mk$",
    r"support/dependencies/[^/]+\.mk$",
    r"support/gnuconfig/config\.",
    r"support/kconfig/",
    r"support/misc/[^/]+\.mk$",
    r"support/testing/tests/.*br2-external/",
    r"toolchain/helpers\.mk$",
    r"toolchain/toolchain-external/pkg-toolchain-external\.mk$",
    ]))

SYSV_INIT_SCRIPT_FILENAME = re.compile(r"/S\d\d[^/]+$")

# For defconfigs: avoid matching kernel, uboot... defconfig files, so
# limit to defconfig files in a configs/ directory, either in-tree or
# in a br2-external tree.
BR_DEFCONFIG_FILENAME = re.compile(r"^(.+/)?configs/[^/]+_defconfig$")


def get_lib_from_filename(fname):
    if flags.intree_only:
        if DO_CHECK_INTREE.match(fname) is None:
            return None
        if DO_NOT_CHECK_INTREE.match(fname):
            return None
    else:
        if os.path.basename(fname) == "external.mk" and \
           os.path.exists(fname[:-2] + "desc"):
            return None
    if fname == ".checkpackageignore":
        return checkpackagelib.lib_ignore
    if CONFIG_IN_FILENAME.search(fname):
        return checkpackagelib.lib_config
    if BR_DEFCONFIG_FILENAME.search(fname):
        return checkpackagelib.lib_defconfig
    if fname.endswith(".hash"):
        return checkpackagelib.lib_hash
    if fname.endswith(".mk") or fname.endswith(".mk.in"):
        return checkpackagelib.lib_mk
    if fname.endswith(".patch"):
        return checkpackagelib.lib_patch
    if SYSV_INIT_SCRIPT_FILENAME.search(fname):
        return checkpackagelib.lib_sysv
    return get_lib_from_filetype(fname)


def common_inspect_rules(m):
    # do not call the base class
    if m.__name__.startswith("_"):
        return False
    if flags.include_list and m.__name__ not in flags.include_list:
        return False
    if flags.exclude_list and m.__name__ in flags.exclude_list:
        return False
    return True


def is_a_check_function(m):
    if not inspect.isclass(m):
        return False
    if not issubclass(m, checkpackagelib.base._CheckFunction):
        return False
    return common_inspect_rules(m)


def is_external_tool(m):
    if not inspect.isclass(m):
        return False
    if not issubclass(m, checkpackagelib.base._Tool):
        return False
    return common_inspect_rules(m)


def print_warnings(warnings, xfail):
    # Avoid the need to use 'return []' at the end of every check function.
    if warnings is None:
        return 0, 0  # No warning generated.

    if xfail:
        return 0, 1  # Warning not generated, fail expected for this file.
    for level, message in enumerate(warnings):
        if flags.verbose >= level:
            print(message.replace("\t", "< tab  >").rstrip())
    return 1, 1  # One more warning to count.


def check_file_using_lib(fname):
    # Count number of warnings generated and lines processed.
    nwarnings = 0
    nlines = 0
    xfail = flags.ignore_list.get(os.path.abspath(fname), [])
    failed = set()

    lib = get_lib_from_filename(fname)
    if not lib:
        if flags.verbose >= VERBOSE_LEVEL_TO_SHOW_IGNORED_FILES:
            print("{}: ignored".format(fname))
        return nwarnings, nlines
    internal_functions = inspect.getmembers(lib, is_a_check_function)
    external_tools = inspect.getmembers(lib, is_external_tool)
    all_checks = internal_functions + external_tools

    if flags.dry_run:
        functions_to_run = [c[0] for c in all_checks]
        print("{}: would run: {}".format(fname, functions_to_run))
        return nwarnings, nlines

    objects = [[f"{lib.__name__[16:]}.{c[0]}", c[1](fname, flags.manual_url)] for c in internal_functions]

    for name, cf in objects:
        warn, fail = print_warnings(cf.before(), name in xfail)
        if fail > 0:
            failed.add(name)
        nwarnings += warn

    lastline = ""
    with open(fname, "r", errors="surrogateescape") as f:
        for lineno, text in enumerate(f):
            nlines += 1
            for name, cf in objects:
                if cf.disable.search(lastline):
                    continue
                line_sts = cf.check_line(lineno + 1, text)
                warn, fail = print_warnings(line_sts, name in xfail)
                if fail > 0:
                    failed.add(name)
                nwarnings += warn
            lastline = text

    for name, cf in objects:
        warn, fail = print_warnings(cf.after(), name in xfail)
        if fail > 0:
            failed.add(name)
        nwarnings += warn

    tools = [[c[0], c[1](fname)] for c in external_tools]

    for name, tool in tools:
        warn, fail = print_warnings(tool.run(), name in xfail)
        if fail > 0:
            failed.add(name)
        nwarnings += warn

    for should_fail in xfail:
        if should_fail not in failed:
            print("{}:0: {} was expected to fail, did you fix the file and forget to update {}?"
                  .format(fname, should_fail, flags.ignore_filename))
            nwarnings += 1

    if flags.failed_only:
        if len(failed) > 0:
            f = " ".join(sorted(failed))
            print("{} {}".format(fname, f))

    return nwarnings, nlines


def __main__():
    global flags
    flags = parse_args()

    if flags.test_suite:
        return checkpackagelib.base.run_test_suite()

    if flags.intree_only:
        # change all paths received to be relative to the base dir
        base_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
        files_to_check = [os.path.relpath(os.path.abspath(f), base_dir) for f in flags.files]
        # move current dir so the script find the files
        os.chdir(base_dir)
    else:
        files_to_check = flags.files

    if len(files_to_check) == 0:
        print("No files to check style")
        sys.exit(1)

    # Accumulate number of warnings generated and lines processed.
    total_warnings = 0
    total_lines = 0

    for fname in files_to_check:
        nwarnings, nlines = check_file_using_lib(fname)
        total_warnings += nwarnings
        total_lines += nlines

    # The warning messages are printed to stdout and can be post-processed
    # (e.g. counted by 'wc'), so for stats use stderr. Wait all warnings are
    # printed, for the case there are many of them, before printing stats.
    sys.stdout.flush()

    if not flags.quiet:
        print("{} lines processed".format(total_lines), file=sys.stderr)
        print("{} warnings generated".format(total_warnings), file=sys.stderr)

    if total_warnings > 0 and not flags.failed_only:
        sys.exit(1)


__main__()
