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

from __future__ import print_function
import argparse
import inspect
import os
import re
import six
import sys

import checkpackagelib.lib_config
import checkpackagelib.lib_hash
import checkpackagelib.lib_mk
import checkpackagelib.lib_patch

VERBOSE_LEVEL_TO_SHOW_IGNORED_FILES = 3
flags = None  # Command line arguments.


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("--manual-url", action="store",
                        default="http://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)")

    return parser.parse_args()


CONFIG_IN_FILENAME = re.compile(r"Config\.\S*$")
DO_CHECK_INTREE = re.compile(r"|".join([
    r"Config.in",
    r"arch/",
    r"boot/",
    r"fs/",
    r"linux/",
    r"package/",
    r"system/",
    r"toolchain/",
    ]))
DO_NOT_CHECK_INTREE = re.compile(r"|".join([
    r"boot/barebox/barebox\.mk$",
    r"fs/common\.mk$",
    r"package/doc-asciidoc\.mk$",
    r"package/pkg-\S*\.mk$",
    r"toolchain/helpers\.mk$",
    r"toolchain/toolchain-external/pkg-toolchain-external\.mk$",
    ]))


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 CONFIG_IN_FILENAME.search(fname):
        return checkpackagelib.lib_config
    if fname.endswith(".hash"):
        return checkpackagelib.lib_hash
    if fname.endswith(".mk"):
        return checkpackagelib.lib_mk
    if fname.endswith(".patch"):
        return checkpackagelib.lib_patch
    return None


def is_a_check_function(m):
    if not inspect.isclass(m):
        return False
    # 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 print_warnings(warnings):
    # Avoid the need to use 'return []' at the end of every check function.
    if warnings is None:
        return 0  # No warning generated.

    for level, message in enumerate(warnings):
        if flags.verbose >= level:
            print(message.replace("\t", "< tab  >").rstrip())
    return 1  # One more warning to count.


def check_file_using_lib(fname):
    # Count number of warnings generated and lines processed.
    nwarnings = 0
    nlines = 0

    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
    classes = inspect.getmembers(lib, is_a_check_function)

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

    objects = [c[1](fname, flags.manual_url) for c in classes]

    for cf in objects:
        nwarnings += print_warnings(cf.before())
    if six.PY3:
        f = open(fname, "r", errors="surrogateescape")
    else:
        f = open(fname, "r")
    lastline = ""
    for lineno, text in enumerate(f.readlines()):
        nlines += 1
        for cf in objects:
            if cf.disable.search(lastline):
                continue
            nwarnings += print_warnings(cf.check_line(lineno + 1, text))
        lastline = text
    f.close()
    for cf in objects:
        nwarnings += print_warnings(cf.after())

    return nwarnings, nlines


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

    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:
        sys.exit(1)


__main__()
