# 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.dev/fuchsia-src/development/editors/youcompleteme
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_build,
                                    'sdk',
                                    'exported',
                                    'zircon_sysroot',
                                    'arch',
                                    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}
