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

    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__()
