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