#!/usr/bin/env python3
#
# Copyright (c) 2019-2021, 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 = (
    'platform/ext',
    'bl2/ext',
    'docs',
    'lib',
    'tools'
)

# 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="origin/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)
