#!/usr/bin/env python3
#
# Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
"""Script to generate configuration files for analysis servers of C++ and Dart.

It generates compile_commands.json for C++ clang and intellij and
analysis_options.yaml for the Dart analyzer.
"""

import argparse
import json
import os
import re
import subprocess
import sys

import generate_buildfiles
import utils

HOST_OS = utils.GuessOS()


def GenerateIdeFiles(options):
    GenerateCompileCommands(options)


def GenerateCompileCommands(options):
    """Generate compile_commands.json for the C++ analysis servers.

  compile_commands.json is used by the c++ clang and intellij language analysis
  servers used in IDEs such as Visual Studio Code and Emacs.

  Args:
    options: supported options include: verbose, force, dir

  Returns:
    success (0) or failure (non zero)
  """

    fname = os.path.join(options.dir, "compile_commands.json")

    if os.path.isfile(fname) and not options.force:
        print(fname + " already exists, use --force to override")
        return

    gn_result = generate_buildfiles.RunGn(options)
    if gn_result != 0:
        return gn_result

    out_folder = utils.GetBuildRoot(HOST_OS,
                                    mode="debug",
                                    arch=options.arch,
                                    target_os=options.os,
                                    sanitizer=options.sanitizer)

    if not os.path.isdir(out_folder):
        return 1

    command_set = json.loads(
        subprocess.check_output([
            "buildtools/ninja/ninja", "-C", out_folder, "-t", "compdb", "-x",
            "cxx", "cc", "h"
        ]))

    commands = []
    for obj in command_set:
        command = obj["command"]

        # Skip precompiled mode, a lot of code is commented out in precompiled mode
        if "-DDART_PRECOMPILED_RUNTIME" in command:
            continue

        # Remove warnings
        command = command.replace("-Werror", "")

        match = re.search(r"(\.\.\/\.\.\/[^ ]+\/clang\/bin\/clang)", command)
        if match:
            command = match.group(1) + command[match.end():]
        else:
            print("Path ending in clang/bin/clang not found in the command.")

        # Remove ninja prepend on Windows.
        # This is not fully correct, as now it fails to find a sysroot for
        # Windows. However, clangd completely fails with the `-t` flag.
        command = re.sub(r"([^\s]*)ninja -t msvc -e environment.x64 --", "",
                         command)

        # Add sysroot from out\DebugX64\environment.x64 on Windows.
        # TODO(dacoharkes): Fetch the paths from that file.
        windowsSysroots = [
            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\27370823e7\\Windows Kits\\10\\Include\\10.0.22621.0\\um',
            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\27370823e7\\Windows Kits\\10\\Include\\10.0.22621.0\\shared',
            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\27370823e7\\Windows Kits\\10\\Include\\10.0.22621.0\\winrt',
            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\27370823e7\\Windows Kits\\10\\Include\\10.0.22621.0\\ucrt',
            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\27370823e7\\VC\\Tools\\MSVC\\14.34.31933\\include',
            'C:\\src\\depot_tools\\win_toolchain\\vs_files\\27370823e7\\VC\\Tools\\MSVC\\14.34.31933\\atlmfc\\include',
        ]
        for windowsSysroot in windowsSysroots:
            command = command.replace(
                "-DDART_TARGET_OS_WINDOWS",
                "-DDART_TARGET_OS_WINDOWS \"-I%s\"" % windowsSysroot)

        # Prevent packing errors from causing fatal_too_many_errors on Windows.
        command = command.replace("-DDART_TARGET_OS_WINDOWS",
                                  "-DDART_TARGET_OS_WINDOWS -ferror-limit=0")

        obj["command"] = command
        commands += [obj]

    with open(fname, "w") as f:
        json.dump(commands, f, indent=4)

    return 0


def main(argv):
    parser = argparse.ArgumentParser(
        description="Python script to generate compile_commands.json and "
        "analysis_options.yaml which are used by the analysis servers for "
        "c++ and Dart.")

    parser.add_argument("-v",
                        "--verbose",
                        help="Verbose output.",
                        action="store_true")

    parser.add_argument("-f",
                        "--force",
                        help="Override files.",
                        action="store_true")

    parser.add_argument("-d",
                        "--dir",
                        help="Target directory.",
                        default=utils.DART_DIR)

    parser.add_argument("-a",
                        "--arch",
                        help="Target architecture for runtime sources.",
                        default="x64")

    parser.add_argument("-s",
                        "--os",
                        help="Target operating system for runtime sources.",
                        default=HOST_OS)

    parser.add_argument('--sanitizer',
                        type=str,
                        help='Build variants (comma-separated).',
                        metavar='[none,asan,lsan,msan,tsan,ubsan]',
                        default='none')

    options = parser.parse_args(argv[1:])

    return GenerateIdeFiles(options)


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