#!/usr/bin/env python3
#
# Copyright (c) 2014, 2016 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2006 The Regents of The University of Michigan
# Copyright (c) 2007,2011 The Hewlett-Packard Development Company
# Copyright (c) 2016 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from abc import ABCMeta, abstractmethod
from difflib import SequenceMatcher
import inspect
import os
import re
import sys

from . import style
from . import sort_includes
from .region import *
from .file_types import lang_type


def safefix(fix_func):
    """Decorator for the fix functions of the Verifier class.
    This function wraps the fix function and creates a backup file
    just in case there is an error.
    """

    def safefix_wrapper(*args, **kwargs):
        # Check to be sure that this is decorating a function we expect:
        # a class method with filename as the first argument (after self)
        assert os.path.exists(args[1])
        self = args[0]
        assert is_verifier(self.__class__)
        filename = args[1]

        # Now, Let's make a backup file.
        from shutil import copyfile

        backup_name = filename + ".bak"
        copyfile(filename, backup_name)

        # Try to apply the fix. If it fails, then we revert the file
        # Either way, we need to clean up our backup file
        try:
            fix_func(*args, **kwargs)
        except Exception as e:
            # Restore the original file to the backup file
            self.ui.write("Error! Restoring the original file.\n")
            copyfile(backup_name, filename)
            raise
        finally:
            # Clean up the backup file
            os.remove(backup_name)

    return safefix_wrapper


def _modified_regions(old, new):
    try:
        m = SequenceMatcher(a=old, b=new, autojunk=False)
    except TypeError:
        # autojunk was introduced in Python 2.7. We need a fallback
        # mechanism to support old Python versions.
        m = SequenceMatcher(a=old, b=new)
    regions = Regions()
    for tag, i1, i2, j1, j2 in m.get_opcodes():
        if tag != "equal":
            regions.extend(Region(i1, i2))
    return regions


class Verifier(object, metaclass=ABCMeta):
    """Base class for style verifiers

    Verifiers check for style violations and optionally fix such
    violations. Implementations should either inherit from this class
    (Verifier) if they need to work on entire files or LineVerifier if
    they operate on a line-by-line basis.

    Subclasses must define these class attributes:
      languages = set of strings identifying applicable languages
      test_name = long descriptive name of test, will be used in
                  messages such as "error in <foo>" or "invalid <foo>"
      opt_name = short name used to generate command-line options to
                 control the test (--fix-<foo>, --ignore-<foo>, etc.)

    """

    def __init__(self, ui, opts, base=None):
        self.ui = ui
        self.base = base

        # opt_name must be defined as a class attribute of derived classes.
        # Check test-specific opts first as these have precedence.
        self.opt_fix = opts.get("fix_" + self.opt_name, False)
        self.opt_ignore = opts.get("ignore_" + self.opt_name, False)
        self.opt_skip = opts.get("skip_" + self.opt_name, False)
        # If no test-specific opts were set, then set based on "-all" opts.
        if not (self.opt_fix or self.opt_ignore or self.opt_skip):
            self.opt_fix = opts.get("fix_all", False)
            self.opt_ignore = opts.get("ignore_all", False)
            self.opt_skip = opts.get("skip_all", False)

    def normalize_filename(self, name):
        abs_name = os.path.abspath(name)
        if self.base is None:
            return abs_name

        abs_base = os.path.abspath(self.base)
        return os.path.relpath(abs_name, start=abs_base)

    def open(self, filename, mode):
        try:
            f = open(filename, mode)
        except OSError as msg:
            print("could not open file {}: {}".format(filename, msg))
            return None

        return f

    def skip(self, filename):
        # We never want to handle symlinks, so always skip them: If the
        # location pointed to is a directory, skip it. If the location is a
        # file inside the gem5 directory, it will be checked as a file, so
        # symlink can be skipped. If the location is a file outside gem5, we
        # don't want to check it anyway.
        if os.path.islink(filename):
            return True
        return lang_type(filename) not in self.languages

    def apply(self, filename, regions=all_regions):
        """Possibly apply to specified regions of file 'filename'.

        Verifier is skipped if --skip-<test> option was provided or if
        file is not of an applicable type.  Otherwise file is checked
        and error messages printed.  Errors are fixed or ignored if
        the corresponding --fix-<test> or --ignore-<test> options were
        provided.  If neither, the user is prompted for an action.

        Returns True to abort, False otherwise.
        """
        if not (self.opt_skip or self.skip(filename)):
            errors = self.check(filename, regions)
            if errors and not self.opt_ignore:
                if self.opt_fix:
                    self.fix(filename, regions)
                else:
                    result = self.ui.prompt(
                        "(a)bort, (i)gnore, or (f)ix?", "aif", "a"
                    )
                    if result == "f":
                        self.fix(filename, regions)
                    elif result == "a":
                        return True  # abort

        return False

    @abstractmethod
    def check(self, filename, regions=all_regions, fobj=None, silent=False):
        """Check specified regions of file 'filename'.

        Given that it is possible that the current contents of the file
        differ from the file as 'staged to commit', for those cases, and
        maybe others, the argument fobj should be a file object open and reset
        with the contents matching what the file would look like after the
        commit. This is needed keep the messages using 'filename' meaningful.

        The argument silent is useful to prevent output when we run check in
        the staged file vs the actual file to detect if the user forgot
        staging fixes to the commit. This way, we prevent reporting errors
        twice in stderr.

        Line-by-line checks can simply provide a check_line() method
        that returns True if the line is OK and False if it has an
        error.  Verifiers that need a multi-line view (like
        SortedIncludes) must override this entire function.

        Returns a count of errors (0 if none), though actual non-zero
        count value is not currently used anywhere.
        """
        pass

    @abstractmethod
    def fix(self, filename, regions=all_regions):
        """Fix specified regions of file 'filename'.

        Line-by-line fixes can simply provide a fix_line() method that
        returns the fixed line. Verifiers that need a multi-line view
        (like SortedIncludes) must override this entire function.
        """
        pass


class LineVerifier(Verifier):
    def check(self, filename, regions=all_regions, fobj=None, silent=False):
        close = False
        if fobj is None:
            fobj = self.open(filename, "rb")
            close = True

        lang = lang_type(filename)
        assert lang in self.languages

        errors = 0
        for num, line in enumerate(fobj):
            if num not in regions:
                continue
            s_line = line.decode("utf-8").rstrip("\n")
            if not self.check_line(s_line, language=lang):
                if not silent:
                    self.ui.write(
                        "invalid %s in %s:%d\n"
                        % (self.test_name, filename, num + 1)
                    )
                    if self.ui.verbose:
                        self.ui.write(">>%s<<\n" % s_line[:-1])
                errors += 1
        if close:
            fobj.close()
        return errors

    @safefix
    def fix(self, filename, regions=all_regions):
        f = self.open(filename, "r+")

        lang = lang_type(filename)
        assert lang in self.languages

        lines = list(f)

        f.seek(0)
        f.truncate()

        for i, line in enumerate(lines):
            line = line.rstrip("\n")
            if i in regions:
                line = self.fix_line(line, language=lang)

            f.write(line)
            f.write("\n")
        f.close()
        self.current_language = None

    @abstractmethod
    def check_line(self, line, **kwargs):
        pass

    @abstractmethod
    def fix_line(self, line, **kwargs):
        pass


class Whitespace(LineVerifier):
    """Check whitespace.

    Specifically:
    - No tabs used for indent
    - No trailing whitespace
    """

    languages = set(
        ("C", "C++", "swig", "python", "asm", "isa", "scons", "make", "dts")
    )
    trail_only = set(("make", "dts"))

    test_name = "whitespace"
    opt_name = "white"

    _lead = re.compile(r"^([ \t]+)")
    _trail = re.compile(r"([ \t]+)$")

    def skip_lead(self, language):
        return language in Whitespace.trail_only

    def check_line(self, line, language):
        if not self.skip_lead(language):
            match = Whitespace._lead.search(line)
            if match and match.group(1).find("\t") != -1:
                return False

        match = Whitespace._trail.search(line)
        if match:
            return False

        return True

    def fix_line(self, line, language):
        if not self.skip_lead(language) and Whitespace._lead.search(line):
            newline = ""
            for i, c in enumerate(line):
                if c == " ":
                    newline += " "
                elif c == "\t":
                    newline += " " * (
                        style.tabsize - len(newline) % style.tabsize
                    )
                else:
                    newline += line[i:]
                    break

            line = newline

        return line.rstrip()


class SortedIncludes(Verifier):
    """Check for proper sorting of include statements"""

    languages = sort_includes.default_languages
    test_name = "include file order"
    opt_name = "include"

    def __init__(self, *args, **kwargs):
        super(SortedIncludes, self).__init__(*args, **kwargs)
        self.sort_includes = sort_includes.SortIncludes()

    def check(self, filename, regions=all_regions, fobj=None, silent=False):
        close = False
        if fobj is None:
            fobj = self.open(filename, "rb")
            close = True
        norm_fname = self.normalize_filename(filename)

        old = [l.decode("utf-8").rstrip("\n") for l in fobj]
        if close:
            fobj.close()

        if len(old) == 0:
            return 0

        language = lang_type(filename, old[0])
        new = list(self.sort_includes(old, norm_fname, language))

        modified = _modified_regions(old, new) & regions

        if modified:
            if not silent:
                self.ui.write(
                    "invalid sorting of includes in %s. Note: If "
                    "there is more than one empty line under the "
                    "#include region, please reduce it to one.\n" % (filename)
                )
                if self.ui.verbose:
                    for start, end in modified.regions:
                        self.ui.write("bad region [%d, %d)\n" % (start, end))
            return 1

        return 0

    @safefix
    def fix(self, filename, regions=all_regions):
        f = self.open(filename, "r+")
        norm_fname = self.normalize_filename(filename)

        old = f.readlines()
        lines = [l.rstrip("\n") for l in old]
        language = lang_type(filename, lines[0])
        sort_lines = list(self.sort_includes(lines, norm_fname, language))
        new = "".join(line + "\n" for line in sort_lines)

        f.seek(0)
        f.truncate()

        for i, line in enumerate(sort_lines):
            f.write(line)
            f.write("\n")
        f.close()


class ControlSpace(LineVerifier):
    """Check for exactly one space after if/while/for"""

    languages = set(("C", "C++"))
    test_name = "spacing after if/while/for"
    opt_name = "control"

    _any_control = re.compile(r"\b(if|while|for)([ \t]*)\(")

    def check_line(self, line, **kwargs):
        match = ControlSpace._any_control.search(line)
        return not (match and match.group(2) != " ")

    def fix_line(self, line, **kwargs):
        new_line = ControlSpace._any_control.sub(r"\1 (", line)
        return new_line


class LineLength(LineVerifier):
    languages = set(("C", "C++", "swig", "python", "asm", "isa", "scons"))
    test_name = "line length"
    opt_name = "length"

    def check_line(self, line, **kwargs):
        return style.normalized_len(line) <= 79

    def fix(self, filename, regions=all_regions, **kwargs):
        self.ui.write("Warning: cannot automatically fix overly long lines.\n")

    def fix_line(self, line):
        pass


class ControlCharacters(LineVerifier):
    languages = set(("C", "C++", "swig", "python", "asm", "isa", "scons"))
    test_name = "control character"
    opt_name = "ascii"

    invalid = "".join(
        [chr(i) for i in range(0, 0x20) if chr(i) not in ("\n", "\t")]
    )

    def check_line(self, line, **kwargs):
        return self.fix_line(line) == line

    def fix_line(self, line, **kwargs):
        return "".join(c for c in line if c not in ControlCharacters.invalid)


class BoolCompare(LineVerifier):
    languages = set(("C", "C++", "python"))
    test_name = "boolean comparison"
    opt_name = "boolcomp"

    regex = re.compile(r"\s*==\s*([Tt]rue|[Ff]alse)\b")

    def check_line(self, line, **kwargs):
        return self.regex.search(line) == None

    def fix_line(self, line, **kwargs):
        match = self.regex.search(line)
        if match:
            if match.group(1) in ("true", "True"):
                line = self.regex.sub("", line)
            else:
                self.ui.write(
                    "Warning: cannot automatically fix "
                    "comparisons with false/False.\n"
                )
        return line


class StructureBraces(LineVerifier):
    """Check if the opening braces of structures are not on the same line of
    the structure name. This includes classes, structs, enums and unions.

    This verifier matches lines starting in optional indent, followed by
    an optional typedef and the structure's keyword, followed by any
    character until the first opening brace is seen. Any extra characters
    after the opening brace are saved for a recursive check, if needed.

    This fixes, for example:
        1) "struct A {"
        2) "enum{"
        3) "    class B { // This is a class"
        4) "union { struct C {"
    to:
        1) "struct A\n{"
        2) "enum\n{"
        3) "    class B\n    {\n        // This is a class"
        4) "union\n{\n        struct C\n        {"

    @todo Make this work for multi-line structure declarations. e.g.,

        class MultiLineClass
          : public BaseClass {
    """

    languages = set(("C", "C++"))
    test_name = "structure opening brace position"
    opt_name = "structurebrace"

    # Matches the indentation of the line
    regex_indentation = "(?P<indentation>\s*)"
    # Matches an optional "typedef" before the keyword
    regex_typedef = "(?P<typedef>(typedef\s+)?)"
    # Matches the structure's keyword
    regex_keyword = "(?P<keyword>class|struct|enum|union)"
    # A negative lookahead to avoid incorrect matches with variable's names
    # e.g., "classifications = {" should not be fixed here.
    regex_avoid = "(?![^\{\s])"
    # Matches anything after the keyword and before the opening brace.
    # e.g., structure name, base type, type of inheritance, etc
    regex_name = "(?P<name>[^\{]*)"
    # Matches anything after the opening brace, which should be
    # parsed recursively
    regex_extra = "(?P<extra>.*)$"
    regex = re.compile(
        r"^"
        + regex_indentation
        + regex_typedef
        + regex_keyword
        + regex_avoid
        + regex_name
        + "\{"
        + regex_extra
    )

    def check_line(self, line, **kwargs):
        return (self.regex.search(line) == None) or (
            line.count("{") == line.count("};")
        )

    def fix_line(self, line, **kwargs):
        match = self.regex.search(line)

        if match:
            # Move the opening brace to the next line
            match_indentation = match.group("indentation")
            match_typedef = match.group("typedef")
            match_keyword = match.group("keyword")
            match_name = match.group("name").rstrip()
            match_extra = match.group("extra").lstrip()
            line = (
                match_indentation
                + match_typedef
                + match_keyword
                + match_name
                + "\n"
                + match_indentation
                + "{"
            )

            # The opening brace should be alone in its own line, so move any
            # extra contents to the next line
            if match_extra != "":
                # Check if the extra line obeys the opening brace rule
                # (in case there are nested declarations)
                line_extra = match_indentation + "    " + match_extra
                if not self.check_line(line_extra):
                    line_extra = self.fix_line(line_extra)
                line += "\n" + line_extra

        return line


def is_verifier(cls):
    """Determine if a class is a Verifier that can be instantiated"""

    return (
        inspect.isclass(cls)
        and issubclass(cls, Verifier)
        and not inspect.isabstract(cls)
    )


# list of all verifier classes
all_verifiers = [
    v for n, v in inspect.getmembers(sys.modules[__name__], is_verifier)
]
