#!/usr/bin/env python
# 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)
