#!/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)

    # 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("Config\.\S*$")
DO_CHECK_INTREE = re.compile("|".join([
    "Config.in",
    "arch/",
    "boot/",
    "fs/",
    "linux/",
    "package/",
    "system/",
    "toolchain/",
    ]))
DO_NOT_CHECK_INTREE = re.compile("|".join([
    "boot/barebox/barebox\.mk$",
    "fs/common\.mk$",
    "package/doc-asciidoc\.mk$",
    "package/pkg-\S*\.mk$",
    "toolchain/helpers\.mk$",
    "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
    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()
    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__()
