# vim: set expandtab:ts=2:sw=2
# Copyright (c) 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.

# Autocompletion config for YouCompleteMe in Fuchsia

import glob
import os
import re
import stat
import subprocess
import ycm_core

# NOTE: paths.py is a direct copy from //build/gn/paths.py
# If there is an issue with the paths not being valid, just pull a new copy.
import sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
import paths as fuchsia_paths

fuchsia_root = os.path.realpath(fuchsia_paths.FUCHSIA_ROOT)
zircon_database = None
zircon_dir = os.path.join(fuchsia_root, 'zircon')
# This doc explains how to generate compile_commands.json for Zircon:
# https://fuchsia.googlesource.com/fuchsia/+/master/docs/zircon/editors.md
if os.path.exists(os.path.join(zircon_dir, 'compile_commands.json')):
  zircon_database = ycm_core.CompilationDatabase(zircon_dir)

os.chdir(fuchsia_root)
fuchsia_build = subprocess.check_output(
    [os.path.join(fuchsia_paths.FUCHSIA_ROOT, 'scripts/fx'),
     'get-build-dir']
    ).strip().decode('utf-8')

fuchsia_clang = os.path.realpath(fuchsia_paths.CLANG_PATH)
fuchsia_sysroot = os.path.join(fuchsia_paths.PREBUILT_PATH,
                               'third_party',
                               'sysroot',
                               fuchsia_paths.get_os())

# Get the clang include paths.
fuchsia_cpp_v1_includes = fuchsia_paths.recursive_search(fuchsia_clang, 'include/c++/v1')
fuchsia_cpp_includes = glob.glob('%s/lib/clang/*/include' % fuchsia_clang)[0]

ninja_path = os.path.realpath(fuchsia_paths.NINJA_PATH)

# Get the name of the zircon project from GN args.
# Reading the args.gn is significantly faster than running `gn args` so we do
# that.
target_cpu = None
args = open(os.path.join(fuchsia_build, 'args.gn')).read()
match = re.search(r'target_cpu\s*=\s*"([^"]+)"', args)
if match:
  target_cpu = match.groups()[0]

common_flags = [
    '-std=c++14',
    '-xc++',
    '-I', fuchsia_root,
    '-I', os.path.join(fuchsia_build, 'gen'),
    '-isystem', os.path.join(fuchsia_sysroot, 'usr', 'include'),
    '-isystem', fuchsia_cpp_v1_includes,
    '-isystem', fuchsia_cpp_includes,
]

arch_flags = []

# Add the sysroot include if we found the zircon project
if target_cpu:
  arch_flags = ['-I' + os.path.join(fuchsia_root,
                                    'out/build-zircon',
                                    'build-' + target_cpu,
                                    'sysroot/include')]

def GetClangCommandFromNinjaForFilename(filename):
  """Returns the command line to build |filename|.

  Asks ninja how it would build the source file. If the specified file is a
  header, tries to find its companion source file first.

  Args:
    filename: (String) Path to source file being edited.

  Returns:
    (List of Strings) Command line arguments for clang.
  """

  # Header files can't be built. Instead, try to match a header file to its
  # corresponding source file.
  if filename.endswith('.h'):
    alternates = ['.cc', '.cpp', '_unittest.cc']
    for alt_extension in alternates:
      alt_name = filename[:-2] + alt_extension
      if os.path.exists(alt_name):
        filename = alt_name
        break
    else:
      # If this is a standalone .h file with no source, the best we can do is
      # try to use the default flags.
      return common_flags

  # Ninja needs the path to the source file from the output build directory.
  # Cut off the common part and /. Also ensure that paths are real and don't
  # contain symlinks that throw the len() calculation off.
  filename = os.path.realpath(filename)
  subdir_filename = filename[len(fuchsia_root) + 1:]
  rel_filename = os.path.join('..', '..', subdir_filename)

  # Ask ninja how it would build our source file.
  ninja_command = [
      ninja_path, '-v', '-C', fuchsia_build, '-t', 'commands',
      rel_filename + '^'
  ]
  p = subprocess.Popen(ninja_command, stdout=subprocess.PIPE)
  stdout, stderr = p.communicate()
  if p.returncode:
    return common_flags
  stdout = stdout.decode('utf-8')

  # Ninja might execute several commands to build something. We want the last
  # clang command.
  clang_line = None
  for line in reversed(stdout.split('\n')):
    if 'clang' in line:
      clang_line = line
      break
  else:
    return common_flags

  # By default we start with the common to every file flags
  fuchsia_flags = []

  # Parse out the -I and -D flags. These seem to be the only ones that are
  # important for YCM's purposes.
  for flag in clang_line.split(' '):
    if flag.startswith('-I'):
      # Relative paths need to be resolved, because they're relative to the
      # output dir, not the source.
      if flag[2] == '/':
        fuchsia_flags.append(flag)
      else:
        abs_path = os.path.normpath(os.path.join(fuchsia_build, flag[2:]))
        fuchsia_flags.append('-I' + abs_path)
    elif ((flag.startswith('-') and flag[1] in 'DWFfmO') or
          flag.startswith('-std=') or flag.startswith('--target=') or
          flag.startswith('--sysroot=')):
      fuchsia_flags.append(flag)
    else:
      print('Ignoring flag: %s' % flag)

  return fuchsia_flags + common_flags


def FlagsForFile(filename):
  """This is the main entry point for YCM. Its interface is fixed.

  Args:
    filename: (String) Path to source file being edited.

  Returns:
    (Dictionary)
      'flags': (List of Strings) Command line flags.
      'do_cache': (Boolean) True if the result should be cached.
  """
  if zircon_database and ('zircon/' in filename):
    zircon_compilation_info = zircon_database.GetCompilationInfoForFile(
      filename)
    if zircon_compilation_info.compiler_flags_:
      return {
        'flags': zircon_compilation_info.compiler_flags_,
        'include_paths_relative_to_dir':
            zircon_compilation_info.compiler_working_dir_,
        'do_cache': True
      }
  file_flags = GetClangCommandFromNinjaForFilename(filename)
  # We add the arch specific flags
  final_flags = file_flags + arch_flags

  return {'flags': final_flags, 'do_cache': True}
