#!/usr/bin/env vpython3

# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
"""This script helps to invoke gn and ninja which lie in depot_tools
repository."""

import json
import os
import re
import shutil
import subprocess
import sys
import tempfile


def find_root_path():
    """Returns the absolute path to the highest level repo root.

    If this repo is checked out as a submodule of the chromium/src
    superproject, this returns the superproect root. Otherwise, it returns the
    webrtc/src repo root.
    """
    root_dir = os.path.dirname(os.path.abspath(__file__))
    while not (os.path.exists(os.path.join(root_dir, 'DEPS'))
               and os.path.exists(os.path.join(root_dir, '.git'))):
        par_dir = os.path.normpath(os.path.join(root_dir, os.pardir))
        if par_dir == root_dir:
            raise RuntimeError('Could not find the repo root.')
        root_dir = par_dir
    return root_dir


ROOT_DIR = find_root_path()
sys.path.append(os.path.join(ROOT_DIR, 'build'))
import find_depot_tools


def run_gn_command(args, root_dir=None):
    """Runs `gn` with provided args and return error if any."""
    try:
        command = [
            sys.executable,
            os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py')
        ] + args
        subprocess.check_output(command, cwd=root_dir)
    except subprocess.CalledProcessError as err:
        return err.output
    return None


# GN_ERROR_RE matches the summary of an error output by `gn check`.
# Matches "ERROR" and following lines until it sees an empty line or a line
# containing just underscores.
GN_ERROR_RE = re.compile(r'^ERROR .+(?:\n.*[^_\n].*$)+', re.MULTILINE)


def run_gn_check(root_dir=None):
    """Runs `gn gen --check` with default args to detect mismatches between
  #includes and dependencies in the BUILD.gn files, as well as general build
  errors.

  Returns a list of error summary strings.
  """
    out_dir = tempfile.mkdtemp('gn')
    try:
        error = run_gn_command(['gen', '--check', out_dir], root_dir)
    finally:
        shutil.rmtree(out_dir, ignore_errors=True)
    return GN_ERROR_RE.findall(error.decode('utf-8')) if error else []


def run_ninja_command(args, root_dir=None):
    """Runs ninja quietly. Any failure (e.g. clang not found) is
     silently discarded, since this is unlikely an error in submitted CL."""
    command = [os.path.join(ROOT_DIR, 'third_party', 'ninja', 'ninja')] + args
    proc = subprocess.Popen(command,
                            cwd=root_dir,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    out, _ = proc.communicate()
    return out


def get_clang_tidy_path():
    """POC/WIP! Use the one we have, even it doesn't match clang's version."""
    tidy = ('third_party/android_toolchain/toolchains/'
            'llvm/prebuilt/linux-x86_64/bin/clang-tidy')
    return os.path.join(ROOT_DIR, tidy)


def get_compilation_db(root_dir=None):
    """Run ninja compdb tool to get proper flags, defines and include paths."""
    # The compdb tool expect a rule.
    commands = json.loads(run_ninja_command(['-t', 'compdb', 'cxx'], root_dir))
    # Turns 'file' field into a key.
    return {v['file']: v for v in commands}


def get_compilation_command(filepath, gn_args, work_dir):
    """Get the whole command used to compile one cc file.
  Typically, clang++ with flags, defines and include paths.

  Args:
      filepath: path to .cc file.
      gen_args: build configuration for gn.
      work_dir: build dir.

  Returns:
    Command as a list, ready to be consumed by subprocess.Popen.
  """
    gn_errors = run_gn_command(['gen'] + gn_args + [work_dir])
    if gn_errors:
        raise RuntimeError('FYI, cannot complete check due to gn error:\n%s\n'
                           'Please open a bug.' % gn_errors)

    # Needed for single file compilation.
    commands = get_compilation_db(work_dir)

    # Path as referenced by ninja.
    rel_path = os.path.relpath(os.path.abspath(filepath), work_dir)

    # Gather defines, include path and flags (such as -std=c++11).
    try:
        compilation_entry = commands[rel_path]
    except KeyError as not_found:
        raise ValueError('%s: Not found in compilation database.\n'
                         'Please check the path.' % filepath) from not_found
    command = compilation_entry['command'].split()

    # Remove troublesome flags. May trigger an error otherwise.
    if '-MMD' in command:
        command.remove('-MMD')
    if '-MF' in command:
        index = command.index('-MF')
        del command[index:index + 2]  # Remove filename as well.

    return command
