#!/usr/bin/env fuchsia-vendored-python
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Runs clang-tidy on modified files.

The tool uses `git diff-index` against the newest parent commit in the upstream
branch (or against HEAD if no such commit is found) in order to find the files
to be formatted. In result, the tool lints files that are locally modified,
staged or touched by any commits introduced on the local branch.
"""

import argparse
import multiprocessing
import os
import platform
import re
import subprocess
import sys

sys.path.append(os.path.dirname(os.path.dirname(__file__)))

import git_utils

FUCHSIA_ROOT = os.path.dirname(  # $root
    os.path.dirname(             # scripts
    os.path.dirname(             # git
    os.path.abspath(__file__))))
PREBUILT_ROOT = os.path.join(FUCHSIA_ROOT, "prebuilt/third_party")

local_os = "linux"
if platform.platform().startswith("Darwin"):
    local_os = "mac"
CLANG_TIDY_TOOL = os.path.join(PREBUILT_ROOT, "clang",
                               "%s-x64" % local_os, "bin",
                               "clang-tidy")
NINJA_TOOL = os.path.join(PREBUILT_ROOT, "ninja",
                               "%s-x64" % local_os, "ninja")

def find_ancestor_with(filepath, relpath):
    """Returns the lowest ancestor of |filepath| that contains |relpath|."""
    cur_dir_path = os.path.abspath(os.path.dirname(filepath))
    while True:
        if os.path.exists(os.path.join(cur_dir_path, relpath)):
            return cur_dir_path

        next_dir_path = os.path.dirname(cur_dir_path)
        if next_dir_path != cur_dir_path:
            cur_dir_path = next_dir_path
        else:
            return None


def get_out_dir(args):
    if args.out_dir:
        out_dir = args.out_dir

        if not os.path.isabs(out_dir):
            out_dir = os.path.join(FUCHSIA_ROOT, out_dir)

        if not os.path.isdir(out_dir):
            print out_dir + " is not a directory"
            sys.exit(-1)
        return out_dir

    fuchsia_config_file = os.path.join(FUCHSIA_ROOT, '.fx-build-dir')
    if os.path.isfile(fuchsia_config_file):
        fuchsia_config = open(fuchsia_config_file).read()
        return os.path.join(FUCHSIA_ROOT, fuchsia_config.strip())

    print("Couldn't find the output directory, pass --out-dir " +
          "(absolute or relative to Fuchsia root)")
    sys.exit(-1)


def generate_db(out_dir):
    cmd = [NINJA_TOOL, "-C", out_dir, "-t", "compdb", "cc", "cxx"]
    db = subprocess.check_output(
        cmd, cwd=FUCHSIA_ROOT, universal_newlines=True)

    # Strip away `gomacc` from the compile commands. This seems to fix problems
    # with clang-tidy not being able to load system headers.
    db = re.sub("\"/[\S]+/gomacc ", "\"", db)

    with open(os.path.join(out_dir, "compile_commands.json"), "w+") as db_file:
        db_file.write(db)


def go(args):
    out_dir = get_out_dir(args)

    # generate the compilation database
    generate_db(out_dir)

    # Find the files to be checked.
    if args.all:
        files = git_utils.get_all_files()
    else:
        files = git_utils.get_diff_files()

    filtered_files = []
    for file_path in files:
        # Skip deleted files.
        if not os.path.isfile(file_path):
            if args.verbose:
                print "skipping " + file_path + " (deleted)"
            continue

        # Skip files with parent directories containing .nolint
        if find_ancestor_with(file_path, ".nolint"):
            if args.verbose:
                print "skipping " + file_path + " (.nolint)"
            continue
        filtered_files.append(file_path)

    if args.verbose:
        print
        print "Files to be checked:"
        for file in filtered_files:
            print " - " + file
        if not filtered_files:
            print " (no files)"
        print

    # change the working directory to Fuchsia root.
    os.chdir(FUCHSIA_ROOT)

    # It's not safe to run in parallel with "--fix", as clang-tidy traverses and
    # fixes header files, and we might end up with concurrent writes to the same
    # header file.
    if args.no_parallel or args.fix:
        parallel_jobs = 1
    else:
        parallel_jobs = multiprocessing.cpu_count()
        print("Running " + str(parallel_jobs) +
              " jobs in parallel, pass --no-parallel to disable")

    jobs = set()

    for file_path in filtered_files:
        _, extension = os.path.splitext(file_path)
        if extension == ".cc":
            relpath = os.path.relpath(file_path)
            cmd = [CLANG_TIDY_TOOL, "-p", out_dir, relpath]
            if args.checks:
                cmd.append("-checks=" + args.checks)
            if args.fix:
                cmd.append("-fix")
            if not args.verbose:
                cmd.append("-quiet")

            if args.verbose:
                print "checking " + file_path + ": " + str(cmd)
            jobs.add(subprocess.Popen(cmd))
            if len(jobs) >= parallel_jobs:
                os.wait()
                jobs.difference_update(
                    [job for job in jobs if job.poll() is not None])
    for job in jobs:
        if job.poll() is None:
            job.wait()


def main():
    parser = argparse.ArgumentParser(description="Lint modified files.")
    parser.add_argument(
        "--all",
        dest="all",
        action=argparse.BooleanOptionalAction,
        default=False,
        help="process all files in the repo under current working directory")
    parser.add_argument(
        "--fix",
        dest="fix",
        action=argparse.BooleanOptionalAction,
        default=False,
        help="automatically generate fixes when possible")
    parser.add_argument("--checks", help="overrides the list of checks to use")
    parser.add_argument(
        "--out-dir",
        help="Output directory, needed to generate compilation db for clang.")
    parser.add_argument(
        "--no-parallel",
        action=argparse.BooleanOptionalAction,
        default=False,
        help="Process one file at a time")
    parser.add_argument(
        "--verbose",
        dest="verbose",
        action=argparse.BooleanOptionalAction,
        default=False,
        help="tell me what you're doing")
    args = parser.parse_args()
    go(args)

    return 0


if __name__ == "__main__":
    sys.exit(main())
