#!/usr/bin/env python3
#
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import argparse
import fnmatch
import logging
import re
import subprocess
from pathlib import Path
from types import SimpleNamespace

import hjson
from tabulate import tabulate


class LicenceHeader(object):
    """Represents the licence header we want to insert"""

    def __init__(self, text):
        self._lines = text.strip().splitlines()

    def __getitem__(self, idx):
        return self._lines.__getitem__(idx)

    def __len__(self):
        return self._lines.__len__()

    def numbered_lines(self, skip=0):
        """Returns an iterator of (line_no, line_text).

        `line_no` counts from 1, and is for humans to count line numbers with.
        use `skip_lines` to skip enumerating the first few lines.
        """
        return enumerate(self._lines[skip:], start=1 + skip)

    @property
    def first_word(self):
        (first_word, _) = self._lines[0].split(' ', 1)
        return first_word


class CommentStyle:
    '''Base class for comment style objects'''

    def __init__(self, first_line_prefix, comment_prefix):
        self.first_line_prefix = first_line_prefix
        self.comment_prefix = comment_prefix

    def search_line_pattern(self, licence_first_word):
        return re.compile(
            re.escape(self.comment_prefix + ' ' + licence_first_word))

    def full_line_parts(self, licence_line):
        return [re.escape(self.comment_prefix), licence_line]

    def full_line_pattern(self, licence_line):
        '''Returns a regex pattern which matches one line of licence text.'''
        return re.compile(' '.join(self.full_line_parts(licence_line)))


class LineCommentStyle(CommentStyle):
    """Helpers for line-style comments."""

    def __init__(self, prefix):
        super().__init__(prefix, prefix)


class DifferentFirstLineCommentStyle(CommentStyle):
    """Some files have a different allowable prefix for their first line."""

    def __init__(self, first_line_prefix, prefix):
        super().__init__(first_line_prefix, prefix)


class BlockCommentStyle(CommentStyle):
    """Helpers for block-style comments."""

    def __init__(self, prefix, suffix):
        super().__init__(prefix, prefix)
        self.comment_suffix = str(suffix)

    def full_line_parts(self, licence_line):
        return [
            re.escape(self.comment_prefix), licence_line,
            re.escape(self.comment_suffix)
        ]


SLASH_SLASH = '//'
HASH = '#'
SLASH_STAR = '/*'

COMMENT_STYLES = {
    SLASH_SLASH: LineCommentStyle("//"),
    HASH: LineCommentStyle("#"),
    SLASH_STAR: BlockCommentStyle("/*", "*/"),
    'corefile': DifferentFirstLineCommentStyle("CAPI=2", "#")
}

# (Prioritised) Mapping of file name suffixes to comment style. If the suffix
# of your file does not match one of these, it will not be checked.
#
# Each entry is a pair (suffixes, styles). suffixes is a list of file suffixes:
# if a filename matches one of these suffixes, we'll use the styles in styles.
# styles is either a string or a list of strings. If there is one or more
# strings, these strings must all be keys of COMMENT_STYLES and they give the
# different comment styles that are acceptable for the file type.
#
# These rules are given in priority order. Tuples higher in the list are
# matched before those later in the list, on purpose.
#
# Files that either do not match any extension or that have an empty list of
# styles are not checked for a licence.
COMMENT_CHARS = [
    # Hardware Files
    ([".svh", ".sv", ".sv.tpl"], SLASH_SLASH),  # SystemVerilog

    # Hardware Build Systems
    ([".tcl", ".sdc"], HASH),  # tcl
    ([".core", ".core.tpl"], 'corefile'),  # FuseSoC Core Files
    (["Makefile", ".mk"], HASH),  # Makefiles
    ([".ys"], HASH),  # Yosys script
    ([".waiver"], HASH),  # AscentLint waiver files
    ([".vlt", ".vlt.tpl"], SLASH_SLASH),  # Verilator cfg (waiver) files
    ([".vbl"], HASH),  # Verible configuration files
    ([".el", ".el.tpl"], SLASH_SLASH),  # Exclusion list
    ([".cfg", ".cfg.tpl"], [SLASH_SLASH,
                            HASH]),  # Kinds of configuration files
    ([".f"], []),  # File lists (not checked)

    # The following two rules will inevitably bite us.
    (["riviera_run.do"], HASH),  # Riviera dofile
    ([".do"], SLASH_SLASH),  # Cadence LEC dofile

    # Software Files
    ([
        ".c", ".c.tpl", ".h", ".h.tpl", ".inc", ".inc.tpl", ".cc", ".cc.tpl",
        ".cpp", ".cpp.tpl"
    ], SLASH_SLASH),  # C, C++
    ([".def"], SLASH_SLASH),  # C, C++ X-Include List Declaration Files
    ([".S"], [SLASH_SLASH, SLASH_STAR]),  # Assembly (With Preprocessing)
    ([".s"], SLASH_STAR),  # Assembly (Without Preprocessing)
    ([".ld", ".ld.tpl"], SLASH_STAR),  # Linker Scripts
    ([".rs", ".rs.tpl"], SLASH_SLASH),  # Rust
    ([".go"], SLASH_SLASH),  # Golang
    ([".proto"], SLASH_SLASH),  # Protobuf

    # Software Build Systems
    (["meson.build", "toolchain.txt", "meson_options.txt"], HASH),  # Meson
    (["WORKSPACE", "BUILD", "BUILD.bazel", ".bzl"], HASH),  # Bazel

    # General Tooling
    ([".py"], HASH),  # Python
    ([".sh"], HASH),  # Shell Scripts
    (["Dockerfile"], HASH),  # Dockerfiles

    # Configuration
    ([".hjson", ".hjson.tpl"], SLASH_SLASH),  # hjson
    ([".yml", ".yaml"], HASH),  # YAML
    ([".toml"], HASH),  # TOML
    (["-requirements.txt"], HASH),  # Apt and Python requirements files
    (["redirector.conf"], HASH),  # nginx config

    # Documentation
    ([".md", ".md.tpl", ".html"], []),  # Markdown and HTML (not checked)
    ([".css"], SLASH_STAR),  # CSS
    ([".scss"], SLASH_SLASH),  # SCSS

    # Templates (Last because there are overlaps with extensions above)
    ([".tpl"], HASH),  # Mako templates
]


class LicenceMatcher:
    '''An object to match a given licence at the start of a file'''

    def __init__(self, comment_style, licence, match_regex):
        self.style = comment_style
        self.expected_lines = list()
        # In case we are using regex matching we can pass the full line "as is"
        if match_regex:
            for i, ll in enumerate(licence):
                try:
                    self.expected_lines.append(
                        comment_style.full_line_pattern(ll))
                    # Catch any regex error here and raise a runtime error.
                except re.error as e:
                    raise RuntimeError(
                        "Can't compile line {} of the licence as a regular expression. Saw `{}`: {}"
                        .format(i, e.pattern[e.pos], e.msg))
            # use the "first line" as a licence marker
            self.search_marker = self.expected_lines[0]
        # For non-regex matching we need to escape everything.
        # This can never throw an exception as everything has been escaped and
        # therefore is always a legal regex.
        else:
            self.search_marker = comment_style.search_line_pattern(
                licence.first_word)
            self.expected_lines = [
                comment_style.full_line_pattern(re.escape(ll))
                for ll in licence
            ]

        self.lines_left = []

    def looks_like_first_line_comment(self, line):
        return line.startswith(self.style.first_line_prefix)

    def looks_like_comment(self, line):
        return line.startswith(self.style.comment_prefix)

    def looks_like_first_line(self, line):
        return self.search_marker.match(line) is not None

    def start(self):
        '''Reset lines_left, to match at the start of the licence'''
        self.lines_left = self.expected_lines

    def take_line(self, line):
        '''Check whether line matches the next line of the licence.

        Returns a pair (matched, done). matched is true if the line matched. If
        this was the last line of the licence, done is true. On a match, this
        increments an internal counter, so the next call to take_line will
        match against the next line of the licence.

        '''
        # If we have no more lines to match, claim a match and that we're done.
        # This shouldn't happen in practice, except if the configuration has an
        # empty licence.
        if not self.lines_left:
            return (True, True)

        next_expected = self.lines_left[0]
        matched = next_expected.fullmatch(line)

        if not matched:
            return (False, False)

        if matched:
            self.lines_left = self.lines_left[1:]
            return (True, not self.lines_left)


def detect_comment_char(all_matchers, filename):
    '''Find zero or more LicenceMatcher objects for filename

    all_matchers should be a dict like COMMENT_STYLES, but where the values are
    the corresponding LicenceMatcher objects.

    '''
    found = None
    for (suffixes, keys) in COMMENT_CHARS:
        if found is not None:
            break
        for suffix in suffixes:
            if filename.endswith(suffix):
                found = keys
                break

    if found is None:
        return []

    if not isinstance(found, list):
        assert isinstance(found, str)
        found = [found]

    return [all_matchers[key] for key in found]


def git_find_repo_toplevel():
    git_output = subprocess.check_output(
        ['git', 'rev-parse', '--show-toplevel'])
    return Path(git_output.decode().strip()).resolve()


def git_find_all_file_paths(top_level, search_paths):
    git_output = subprocess.check_output(
        ["git", "-C",
         str(top_level), "ls-files", "-z", "--", *search_paths])
    for path in git_output.rstrip(b"\0").split(b"\0"):
        yield Path(top_level, path.decode())


class ResultsTracker(object):
    """Helper for tracking results"""

    def __init__(self, base_dir):
        self.base_dir = base_dir

    passed_count = 0
    failed_count = 0
    excluded_count = 0
    skipped_count = 0

    failing_paths = set()

    @property
    def total_count(self):
        return (self.passed_count + self.failed_count + self.skipped_count +
                self.excluded_count)

    def passed(self, path, line_no, reason):
        rel_path = path.relative_to(self.base_dir)
        logging.debug("%s:%d PASSED: %s", str(rel_path), line_no, reason)
        self.passed_count += 1

    def failed(self, path, line_no, reason):
        rel_path = path.relative_to(self.base_dir)
        logging.error("%s:%d FAILED: %s", str(rel_path), line_no, reason)
        self.failing_paths.add(rel_path)
        self.failed_count += 1

    def skipped(self, path, reason):
        rel_path = path.relative_to(self.base_dir)
        logging.info("%s: SKIPPED: %s", str(rel_path), reason)
        self.skipped_count += 1

    def excluded(self, path, reason):
        rel_path = path.relative_to(self.base_dir)
        logging.debug("%s: EXCLUDED: %s", str(rel_path), reason)
        self.excluded_count += 1

    def any_failed(self):
        return self.failed_count > 0

    def display_nicely(self):
        headers = ["Results:", "Files"]
        results = [["Passed", self.passed_count],
                   ["Failed", self.failed_count],
                   ["Skipped", self.skipped_count],
                   ["Excluded", self.excluded_count],
                   ["Total", self.total_count]]

        return tabulate(results, headers, tablefmt="simple")


def matches_exclude_pattern(config, file_path):
    rel_path = str(file_path.relative_to(config.base_dir))
    for exclude_pattern in config.exclude_paths:
        if fnmatch.fnmatch(rel_path, exclude_pattern):
            return True
    return False


def check_paths(config, git_paths):
    results = ResultsTracker(config.base_dir)
    try:
        all_matchers = {
            key: LicenceMatcher(style, config.licence, config.match_regex)
            for key, style in COMMENT_STYLES.items()
        }
    except RuntimeError as e:
        exit(e)

    for filepath in git_find_all_file_paths(config.base_dir, git_paths):
        # Skip symlinks (with message)
        if filepath.is_symlink():
            results.excluded(filepath, "File is a symlink")
            continue

        # Skip non-file
        if not filepath.is_file():
            continue

        # Skip exclude patterns
        if matches_exclude_pattern(config, filepath):
            results.excluded(filepath, "Path matches exclude pattern")
            continue

        check_file_for_licence(all_matchers, results, filepath)

    return results


def check_file_for_licence(all_matchers, results, filepath):
    matchers = detect_comment_char(all_matchers, filepath.name)

    if not matchers:
        results.skipped(filepath, "Unknown comment style")
        return

    if filepath.stat().st_size == 0:
        results.skipped(filepath, "Empty file")
        return

    problems = []
    for matcher in matchers:
        good, line_num, msg = check_file_with_matcher(matcher, filepath)
        if good:
            results.passed(filepath, line_num, msg)
            return
        else:
            problems.append((line_num, msg))

    # If we get here, we didn't find a matching licence
    for line_num, msg in problems:
        results.failed(filepath, line_num, msg)


def check_file_with_matcher(matcher, filepath):
    '''Check the file at filepath against matcher.

    Returns a tuple (is_good, line_number, msg). is_good is True on success;
    False on failure. line_number is the position where the licence was found
    (on success) or where we gave up searching for it (on failure). msg is the
    associated success or error message.

    '''

    def next_line(file, line_no):
        return (next(file).rstrip(), line_no + 1)

    with filepath.open() as f:
        licence_assumed_start = None

        # Get first line
        try:
            line, line_no = next_line(f, 0)
        except StopIteration:
            return (False, 1, "Empty file")

        # Check first line against the first word of licence, or against a
        # possible different first line.
        if not matcher.looks_like_first_line(line):
            if not matcher.looks_like_first_line_comment(line):
                return (False, line_no, "File does not start with comment")

            try:
                line, line_no = next_line(f, line_no)
            except StopIteration:
                return (False, line_no,
                        "Reached end of file before finding licence")

        # Skip lines that don't seem to be the first line of the licence
        while not matcher.looks_like_first_line(line):
            try:
                line, line_no = next_line(f, line_no)
            except StopIteration:
                return (False, line_no,
                        "Reached end of file before finding licence")

            if not matcher.looks_like_comment(line):
                return (False, line_no,
                        "First comment ended before licence notice")

        # We found the marker, so we found the first line of the licence. The
        # current line is in the first comment, so check the line matches the
        # expected first line:
        licence_assumed_start = line_no
        matcher.start()
        matched, done = matcher.take_line(line)
        if not matched:
            return (False, line_no, "Licence does not match")

        while not done:
            try:
                line, line_no = next_line(f, line_no)
            except StopIteration:
                return (False, line_no,
                        "Reached end of file before finding licence")

            # Check against full expected line.
            matched, done = matcher.take_line(line)
            if not matched:
                return (False, line_no, "Licence did not match")

    return (True, licence_assumed_start, "Licence found")


def main():
    desc = "A tool to check the lowRISC licence header is in each source file"
    parser = argparse.ArgumentParser(description=desc)
    parser.add_argument("--config",
                        metavar="config.hjson",
                        type=argparse.FileType('r', encoding='UTF-8'),
                        required=True,
                        help="HJSON file to read for licence configuration.")
    parser.add_argument("paths",
                        metavar="path",
                        nargs='*',
                        default=["."],
                        help="Paths to check for licence headers.")
    parser.add_argument('-v',
                        "--verbose",
                        action='store_true',
                        dest='verbose',
                        help="Verbose output")

    options = parser.parse_args()

    if options.verbose:
        logging.basicConfig(format="%(levelname)s: %(message)s",
                            level=logging.INFO)
    else:
        logging.basicConfig(format="%(levelname)s: %(message)s")

    config = SimpleNamespace()
    config.base_dir = git_find_repo_toplevel()

    parsed_config = hjson.load(options.config)

    config.licence = LicenceHeader(parsed_config['licence'])
    config.exclude_paths = set(parsed_config['exclude_paths'])
    # Check whether we should use regex matching or full string matching.
    match_regex = parsed_config.get('match_regex', 'false')
    if match_regex not in ['true', 'false']:
        print('Invalid value for match_regex: {!r}. '
              'Should be "true" or "false".'.format(match_regex))
        exit(1)
    config.match_regex = match_regex == 'true'

    results = check_paths(config, options.paths)

    print(results.display_nicely())

    if results.any_failed():
        print("Failed:")
        for path in results.failing_paths:
            print("  {}".format(str(path)))
        print("")
        exit(1)
    else:
        exit(0)


if __name__ == '__main__':
    main()
