#!/usr/bin/env python3
#
# Copyright (c) 2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#

import argparse
import os
import re
import sys
import utils

# File extensions to check
VALID_FILE_EXTENSIONS = ('.c', '.S', '.h')

# Paths inside the tree to ignore. Hidden folders and files are always ignored.
# They mustn't end in '/'.
IGNORED_FOLDERS = (
    "tools",
    "docs"
)

# List of ignored files in folders that aren't ignored
IGNORED_FILES = ()

# Regular expression for searching the Banned APIs. This is taken from the
# Coding guideline in TF-A repo
BANNED_APIS = ["strcpy", "wcscpy", "strncpy", "strcat", "wcscat", "strncat",
               "sprintf", "vsprintf", "strtok", "atoi", "atol", "atoll",
               "itoa", "ltoa", "lltoa"]
BANNED_PATTERN = re.compile('\(|'.join(BANNED_APIS))

COMMENTS_PATTERN = re.compile(r"//|/\*|\*/")


def filter_comments(f):
    '''
    filter_comments(f) -> iterator for line number, filtered line

    Given an iterable of lines (such as a file), return another iterable of
    lines, with the comments filtered out and removed.
    '''

    in_comment = False
    for line_num, line in enumerate(f):
        line = line.rstrip('\n')

        temp = ""
        breaker = len(line) if in_comment else 0
        for match in COMMENTS_PATTERN.finditer(line):
            content = match.group(0)
            start, end = match.span()

            if in_comment:
                if content == "*/":
                    in_comment = False
                    breaker = end
            else:
                if content == "/*":
                    in_comment = True
                    temp += line[breaker:start]
                    breaker = len(line)
                elif content == "//":
                    temp += line[breaker:start]
                    breaker = len(line)
                    break

        temp += line[breaker:]
        if temp:
            yield line_num + 1, temp


def file_check_banned_api(path, encoding='utf-8'):
    '''
    Reads all lines from a file in path and checks for any banned APIs.
    The combined number of errors and uses of banned APIs is returned. If the
    result is equal to 0, the file is clean and contains no banned APIs.
    '''

    count = 0

    try:
        f = open(path, encoding=encoding)
    except FileNotFoundError:
        print("ERROR: could not open " + path)
        utils.print_exception_info()
        return True

    try:
        for line_num, line in filter_comments(f):
            match = BANNED_PATTERN.search(line)
            if match:
                location = "line {} of file {}".format(line_num, path)
                print("BANNED API: in " + location)

                # NOTE: this preview of the error is not perfect if comments
                # have been removed - however, it does good enough most of the
                # time.
                start, end = match.span()
                print(">>> {}".format(line))
                print("    {}^{}".format(start * " ", (end - start - 1) * "~"))

                count += 1
    except:
        print("ERROR: unexpected exception while parsing " + path)
        utils.print_exception_info()
        count += 1

    f.close()

    return count


def get_tree_files():
    '''
    Get all files in the git repository
    '''

    # Get patches of the affected commits with one line of context.
    (rc, stdout, stderr) = utils.shell_command(['git', 'ls-files'])
    if rc != 0:
        return False

    lines = stdout.splitlines()
    return lines


def get_patch_files(base_commit, end_commit):
    '''
    Get all files that have changed in a given patch
    '''

    # Get patches of the affected commits with one line of context.
    (rc, stdout, stderr) = utils.shell_command([
        'git', 'diff-tree', '--diff-filter=ACMRT', '-r', '--name-only',
        base_commit, end_commit])

    if rc != 0:
        return False

    paths = stdout.splitlines()
    return paths


def parse_cmd_line():
    parser = argparse.ArgumentParser(
        description="Check Banned APIs",
        epilog="""
            For each source file in the tree, checks whether Banned APIs as
            described in the list are used or not.
        """
    )

    parser.add_argument("--tree", "-t",
                        help="""
                        Path to the source tree to check (default: %(default)s)
                        """,
                        default=os.curdir)
    parser.add_argument("--patch", "-p",
                        help="""
                        Patch mode. Instead of checking all files in
                        the source tree, the script will consider only files
                        that are modified by the latest patch(es).
                        """,
                        action="store_true")
    parser.add_argument("--from-ref",
                        help="""
                        Base commit in patch mode (default: %(default)s)
                        """,
                        default="master")
    parser.add_argument("--to-ref",
                        help="""
                        Final commit in patch mode (default: %(default)s)
                        """,
                        default="HEAD")
    parser.add_argument("--verbose", "-v",
                        help="Print verbose output",
                        action="store_true")
    args = parser.parse_args()
    return args


if __name__ == "__main__":
    args = parse_cmd_line()

    os.chdir(args.tree)

    if args.patch:
        print("Checking files modified between patches " + args.from_ref +
              " and " + args.to_ref + "...\n")
        files = get_patch_files(args.from_ref, args.to_ref)
    else:
        print("Checking all files git repo " + os.path.abspath(args.tree) +
              "...\n")
        files = get_tree_files()

    total_errors = 0
    for filename in files:
        ignored = utils.file_is_ignored(filename, VALID_FILE_EXTENSIONS,
                                        IGNORED_FILES, IGNORED_FOLDERS)
        if ignored:
            if args.verbose:
                print("INFO: Skipping ignored file " + filename)
            continue

        if args.verbose:
            print("INFO: Checking " + filename)

        total_errors += file_check_banned_api(filename)

    print(str(total_errors) + " errors found")

    if total_errors == 0:
        sys.exit(0)
    else:
        sys.exit(1)
