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

from __future__ import print_function
import argparse
import multiprocessing as mp
import lintutils
from subprocess import PIPE
import sys
from functools import partial


def _get_chunk_key(filenames):
    # lists are not hashable so key on the first filename in a chunk
    return filenames[0]


# clang-tidy outputs complaints in '/path:line_number: complaint' format,
# so we can scan its output to get a list of files to fix
def _check_some_files(completed_processes, filenames):
    result = completed_processes[_get_chunk_key(filenames)]
    return lintutils.stdout_pathcolonline(result, filenames)


def _check_all(cmd, filenames):
    # each clang-tidy instance will process 16 files
    chunks = lintutils.chunk(filenames, 16)
    cmds = [cmd + some for some in chunks]
    results = lintutils.run_parallel(cmds, stderr=PIPE, stdout=PIPE)
    error = False
    # record completed processes (keyed by the first filename in the input
    # chunk) for lookup in _check_some_files
    completed_processes = {
        _get_chunk_key(some): result
        for some, result in zip(chunks, results)
    }
    checker = partial(_check_some_files, completed_processes)
    pool = mp.Pool()
    try:
        # check output of completed clang-tidy invocations in parallel
        for problem_files, stdout in pool.imap(checker, chunks):
            if problem_files:
                msg = "clang-tidy suggested fixes for {}"
                print("\n".join(map(msg.format, problem_files)))
                error = True
    except Exception:
        error = True
        raise
    finally:
        pool.terminate()
        pool.join()

    if error:
        sys.exit(1)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Runs clang-tidy on all ")
    parser.add_argument("--clang_tidy_binary",
                        required=True,
                        help="Path to the clang-tidy binary")
    parser.add_argument("--exclude_globs",
                        help="Filename containing globs for files "
                        "that should be excluded from the checks")
    parser.add_argument("--compile_commands",
                        required=True,
                        help="compile_commands.json to pass clang-tidy")
    parser.add_argument("--source_dir",
                        required=True,
                        help="Root directory of the source code")
    parser.add_argument("--fix", default=False,
                        action="store_true",
                        help="If specified, will attempt to fix the "
                        "source code instead of recommending fixes, "
                        "defaults to %(default)s")
    parser.add_argument("--quiet", default=False,
                        action="store_true",
                        help="If specified, only print errors")
    arguments = parser.parse_args()

    exclude_globs = []
    if arguments.exclude_globs:
        for line in open(arguments.exclude_globs):
            exclude_globs.append(line.strip())

    linted_filenames = []
    for path in lintutils.get_sources(arguments.source_dir, exclude_globs):
        linted_filenames.append(path)

    if not arguments.quiet:
        msg = 'Tidying {}' if arguments.fix else 'Checking {}'
        print("\n".join(map(msg.format, linted_filenames)))

    cmd = [
        arguments.clang_tidy_binary,
        '-p',
        arguments.compile_commands
    ]
    if arguments.fix:
        cmd.append('-fix')
        results = lintutils.run_parallel(
            [cmd + some for some in lintutils.chunk(linted_filenames, 16)])
        for returncode, stdout, stderr in results:
            if returncode != 0:
                sys.exit(returncode)

    else:
        _check_all(cmd, linted_filenames)
