#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import argparse
import re
import os

parser = argparse.ArgumentParser(
    description="Check for illegal headers for C++/CLI applications")
parser.add_argument("source_path",
                    help="Path to source code")
arguments = parser.parse_args()


_STRIP_COMMENT_REGEX = re.compile('(.+)?(?=//)')
_NULLPTR_REGEX = re.compile(r'.*\bnullptr\b.*')
_RETURN_NOT_OK_REGEX = re.compile(r'.*\sRETURN_NOT_OK.*')
_ASSIGN_OR_RAISE_REGEX = re.compile(r'.*\sASSIGN_OR_RAISE.*')


def _paths(paths):
    return [p.strip().replace('/', os.path.sep) for p in paths.splitlines()]


def _strip_comments(line):
    m = _STRIP_COMMENT_REGEX.match(line)
    if not m:
        return line
    else:
        return m.group(0)


def lint_file(path):
    fail_rules = [
        # rule, error message, rule-specific exclusions list
        (lambda x: '<mutex>' in x, 'Uses <mutex>', []),
        (lambda x: '<iostream>' in x, 'Uses <iostream>', []),
        (lambda x: re.match(_NULLPTR_REGEX, x), 'Uses nullptr', []),
        (lambda x: re.match(_RETURN_NOT_OK_REGEX, x),
         'Use ARROW_RETURN_NOT_OK in header files', _paths('''\
         arrow/status.h
         test
         arrow/util/hash.h
         arrow/python/util''')),
        (lambda x: re.match(_ASSIGN_OR_RAISE_REGEX, x),
         'Use ARROW_ASSIGN_OR_RAISE in header files', _paths('''\
         arrow/result_internal.h
         test
         '''))

    ]

    with open(path) as f:
        for i, line in enumerate(f):
            stripped_line = _strip_comments(line)
            for rule, why, rule_exclusions in fail_rules:
                if any([True for excl in rule_exclusions if excl in path]):
                    continue

                if rule(stripped_line):
                    yield path, why, i, line


EXCLUSIONS = _paths('''\
    arrow/arrow-config.cmake
    arrow/python/iterators.h
    arrow/util/hashing.h
    arrow/util/macros.h
    arrow/util/parallel.h
    arrow/vendored
    arrow/visitor_inline.h
    gandiva/cache.h
    gandiva/jni
    jni/
    test
    internal
    _generated''')


def lint_files():
    for dirpath, _, filenames in os.walk(arguments.source_path):
        for filename in filenames:
            full_path = os.path.join(dirpath, filename)

            exclude = False
            for exclusion in EXCLUSIONS:
                if exclusion in full_path:
                    exclude = True
                    break

            if exclude:
                continue

            # Lint file name, except for pkg-config templates
            if not filename.endswith('.pc.in'):
                if '-' in filename:
                    why = ("Please use underscores, not hyphens, "
                           "in source file names")
                    yield full_path, why, 0, full_path

            # Only run on header files
            if filename.endswith('.h'):
                for _ in lint_file(full_path):
                    yield _


if __name__ == '__main__':
    failures = list(lint_files())
    for path, why, i, line in failures:
        print('File {0} failed C++/CLI lint check: {1}\n'
              'Line {2}: {3}'.format(path, why, i + 1, line))
    if failures:
        exit(1)
