#!/usr/bin/env python3
# Copyright 2020 the V8 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.

"""\
Creates a "compile_commands.json" file for V8, for the needs of clangd and
similar code indexers. Also updates generated C++ sources, and compiles the
Torque Language Server, for a complete code indexing experience.
"""

import json
import os
import subprocess
import sys

PYLIB_PATH = 'tools/clang/pylib'
GM_PATH = 'tools/dev'
PYLIB_CHECK = os.path.join(PYLIB_PATH, 'clang', 'compile_db.py')
GM_CHECK = os.path.join(GM_PATH, 'gm.py')
def CheckRelativeImport(path):
  if not os.path.exists(path):
    print("Error: Please run this script from the root of a V8 checkout. %s "
          "must be a valid relative path." % path)
    sys.exit(1)
CheckRelativeImport(PYLIB_CHECK)
CheckRelativeImport(GM_CHECK)

sys.path.insert(0, PYLIB_PATH)
from clang import compile_db

sys.path.insert(0, GM_PATH)
import gm

def _Call(cmd, silent=False):
  if not silent: print("# %s" % cmd)
  return subprocess.call(cmd, shell=True)

def _Write(filename, content):
  with open(filename, "w") as f:
    f.write(content)

def PrepareBuildDir(arch, mode):
  build_dir = os.path.join("out", "%s.%s" % (arch, mode))
  if not os.path.exists(build_dir):
    print("# mkdir -p %s" % build_dir)
    os.makedirs(build_dir)
  args_gn = os.path.join(build_dir, "args.gn")
  if not os.path.exists(args_gn):
    conf = gm.Config(arch, mode, [])
    _Write(args_gn, conf.GetGnArgs())
  build_ninja = os.path.join(build_dir, "build.ninja")
  if not os.path.exists(build_ninja):
    code = _Call("gn gen %s" % build_dir)
    if code != 0: raise Error("gn gen failed")
  else:
    _Call("ninja -C %s build.ninja" % build_dir)
  return build_dir

def AddTargetsForArch(arch, combined):
  build_dir = PrepareBuildDir(arch, "debug")
  commands = compile_db.ProcessCompileDatabaseIfNeeded(
                compile_db.GenerateWithNinja(build_dir, ["all"]))
  added = 0
  for c in commands:
    key = c["file"]
    if key not in combined:
      combined[key] = c
      added += 1
  print("%s: added %d compile commands" % (arch, added))

def UpdateCompileCommands():
  print(">>> Updating compile_commands.json...")
  combined = {}
  AddTargetsForArch("x64", combined)
  AddTargetsForArch("ia32", combined)
  AddTargetsForArch("arm", combined)
  AddTargetsForArch("arm64", combined)
  commands = []
  for key in combined:
    commands.append(combined[key])
  _Write("compile_commands.json", json.dumps(commands, indent=2))

def CompileLanguageServer():
  print(">>> Compiling Torque Language Server...")
  PrepareBuildDir("x64", "release")
  _Call("autoninja -C out/x64.release torque-language-server")

def GenerateCCFiles():
  print(">>> Generating generated C++ source files...")
  # This must be called after UpdateCompileCommands().
  assert os.path.exists("out/x64.debug/build.ninja")
  _Call("autoninja -C out/x64.debug v8_generated_cc_files")

def StartGoma():
  gomadir = gm.DetectGoma()
  if (gomadir is not None and
      _Call("ps -e | grep compiler_proxy > /dev/null", silent=True) != 0):
    _Call("%s/goma_ctl.py ensure_start" % gomadir)

if __name__ == "__main__":
  StartGoma()
  CompileLanguageServer()
  UpdateCompileCommands()
  GenerateCCFiles()
