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