#!/usr/bin/python

# Copyright 2017 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# ==============================================================================
# This .ycm_extra_conf will be picked up automatically for code completion using
# YouCompleteMe.
# 
# See https://valloric.github.io/YouCompleteMe/ for instructions on setting up
# YouCompleteMe using Vim. This .ycm_extra_conf file also works with any other
# completion engine that uses YCMD (https://github.com/Valloric/ycmd).
# 
# Code completion depends on a Clang compilation database. This is placed in a
# file named `compile_commands.json` in your execution root path. I.e. it will
# be at the path returned by `bazel info execution_root`.
# 
# If the compilation database isn't available, this script will generate one
# using tools/cpp/generate_compilation_database.sh. This process can be slow if
# you haven't built the sources yet. It's always a good idea to run
# generate_compilation_database.sh manually so that you can see the build output
# including any errors encountered during compile command generation.
# ==============================================================================

import json
import os
import shlex
import subprocess
import time

# If all else fails, then return this list of flags.
DEFAULT_FLAGS = []

CANONICAL_SOURCE_FILE = 'kythe/cxx/extractor/cxx_extractor_main.cc'

# Full path to directory containing compilation database. This is usually
# |execution_root|/compile_commands.json.
COMPILATION_DATABASE_PATH = None

# Workspace path.
WORKSPACE_PATH = None

# The compilation database. This is a mapping from the absolute normalized path
# of the source file to it's compile command broken down into an array.
COMPILATION_DATABASE = {}

# If loading the compilation database failed for some reason,
# LAST_INIT_FAILURE_TIME contains the value of time.clock() at the time the
# failure was encountered.
LAST_INIT_FAILURE_TIME = None

# If this many seconds have passed since the last failure, then try to generate
# the compilation database again.
RETRY_TIMEOUT_SECONDS = 120

HEADER_EXTENSIONS = ['.h', '.hpp', '.hh', '.hxx']
SOURCE_EXTENSIONS = ['.cc', '.cpp', '.c', '.m', '.mm', '.cxx']

NORMALIZE_PATH = 1
REMOVE = 2

# List of clang options and what to do with them. Use the '-foo' form for flags
# that could be used as '-foo <arg>' and '-foo=<arg>' forms, and use '-foo=' for
# flags that can only be used as '-foo=<arg>'.
#
# Mapping a flag to NORMALIZE_PATH causes its argument to be normalized against
# the build directory via ExpandAndNormalizePath(). REMOVE causes both the flag
# and its value to be removed.
CLANG_OPTION_DISPOSITION = {
    '-I': NORMALIZE_PATH,
    '-MF': REMOVE,
    '-cxx-isystem': NORMALIZE_PATH,
    '-dependency-dot': REMOVE,
    '-dependency-file': REMOVE,
    '-fbuild-session-file': REMOVE,
    '-fmodule-file': NORMALIZE_PATH,
    '-fmodule-map-file': NORMALIZE_PATH,
    '-foptimization-record-file': REMOVE,
    '-fprebuilt-module-path': NORMALIZE_PATH,
    '-fprofile-generate=': REMOVE,
    '-fprofile-instrument-generate=': REMOVE,
    '-fprofile-user=': REMOVE,
    '-gcc-tollchain=': NORMALIZE_PATH,
    '-idirafter': NORMALIZE_PATH,
    '-iframework': NORMALIZE_PATH,
    '-imacros': NORMALIZE_PATH,
    '-include': NORMALIZE_PATH,
    '-include-pch': NORMALIZE_PATH,
    '-iprefix': NORMALIZE_PATH,
    '-iquote': NORMALIZE_PATH,
    '-isysroot': NORMALIZE_PATH,
    '-isystem': NORMALIZE_PATH,
    '-isystem-after': NORMALIZE_PATH,
    '-ivfsoverlay': NORMALIZE_PATH,
    '-iwithprefixbefore': NORMALIZE_PATH,
    '-iwithsysroot': NORMALIZE_PATH,
    '-o': REMOVE,
    '-working-directory': NORMALIZE_PATH,
}


def ProcessOutput(args):
  """Run the program described by |args| and return its stdout as a stream.

  |stderr| and |stdin| will be set to /dev/null. Will raise CalledProcessError
  if the subprocess doesn't complete successfully.
  """
  output = ''
  with open(os.devnull, 'w') as err:
    with open(os.devnull, 'r') as inp:
      output = subprocess.check_output(args, stderr=err, stdin=inp)
  return str(output).strip()


def InitBazelConfig():
  """Initialize globals based on Bazel configuration.

  Initialize COMPILATION_DATABASE_PATH, WORKSPACE_PATH, and
  CANONICAL_SOURCE_FILE based on Bazel. These values are not expected to change
  during the session."""
  global COMPILATION_DATABASE_PATH
  global WORKSPACE_PATH
  global CANONICAL_SOURCE_FILE
  execution_root = ProcessOutput(['bazel', 'info', 'execution_root'])
  COMPILATION_DATABASE_PATH = os.path.join(execution_root,
                                           'compile_commands.json')
  WORKSPACE_PATH = ProcessOutput(['bazel', 'info', 'workspace'])
  CANONICAL_SOURCE_FILE = ExpandAndNormalizePath(CANONICAL_SOURCE_FILE,
                                                 WORKSPACE_PATH)


def GenerateCompilationDatabaseSlowly():
  """Generate compilation database. May take a while."""
  script_path = os.path.join(WORKSPACE_PATH, 'tools', 'cpp',
                             'generate_compilation_database.sh')
  ProcessOutput(script_path)


def ExpandAndNormalizePath(filename, basepath=WORKSPACE_PATH):
  """Resolves |filename| relative to |basepath| and expands symlinks."""
  if not os.path.isabs(filename) and basepath:
    filename = os.path.join(basepath, filename)
  filename = os.path.realpath(filename)
  return str(filename)


def PrepareCompileFlags(compile_command, basepath):
  flags = shlex.split(compile_command)
  flags_to_return = []
  use_next_flag_as_value_for = None

  def HandleFlag(name, value, combine):
    disposition = CLANG_OPTION_DISPOSITION.get(name, None)
    if disposition is None and combine:
      disposition = CLANG_OPTION_DISPOSITION.get(name + '=', None)

    if disposition == REMOVE:
      return

    if disposition == NORMALIZE_PATH:
      value = ExpandAndNormalizePath(value, basepath)

    if combine:
      flags_to_return.append('{}={}'.format(name, value))
    else:
      flags_to_return.extend([name, value])

  for flag in flags:
    if use_next_flag_as_value_for is not None:
      name = use_next_flag_as_value_for
      use_next_flag_as_value_for = None
      HandleFlag(name, flag, combine=False)
      continue

    if '=' in flag:  # -foo=bar
      name, value = flag.split('=', 1)
      HandleFlag(name, value, combine=True)
      continue

    if flag in CLANG_OPTION_DISPOSITION:
      use_next_flag_as_value_for = flag
      continue

    if flag.startswith('-I'):
      HandleFlag('-I', flags[3:], combine=False)
      continue

    flags_to_return.append(flag)

  return flags_to_return


def LoadCompilationDatabase():
  if not os.path.exists(COMPILATION_DATABASE_PATH):
    GenerateCompilationDatabaseSlowly()

  with open(COMPILATION_DATABASE_PATH, 'r') as database:
    database_dict = json.load(database)

  global COMPILATION_DATABASE
  COMPILATION_DATABASE = {}

  for entry in database_dict:
    filename = ExpandAndNormalizePath(entry['file'], WORKSPACE_PATH)
    directory = entry['directory']
    command = entry['command']
    COMPILATION_DATABASE[filename] = {
        'command': command,
        'directory': directory
    }


def IsHeaderFile(filename):
  extension = os.path.splitext(filename)[1]
  return extension in HEADER_EXTENSIONS


def FindAlternateFile(filename):
  if IsHeaderFile(filename):
    basename = os.path.splitext(filename)[0]
    for extension in SOURCE_EXTENSIONS:
      new_filename = basename + extension
      if new_filename in COMPILATION_DATABASE:
        return new_filename

  # Try something in the same directory.
  directory = os.path.dirname(filename)
  for key in COMPILATION_DATABASE.iterkeys():
    if key.startswith(directory) and os.path.dirname(key) == directory:
      return key

  return CANONICAL_SOURCE_FILE


# Entrypoint for YouCompleteMe.
def FlagsForFile(filename, **kwargs):
  global LAST_INIT_FAILURE_TIME

  if len(COMPILATION_DATABASE) == 0:
    if LAST_INIT_FAILURE_TIME is not None and time.clock(
    ) - LAST_INIT_FAILURE_TIME < RETRY_TIMEOUT_SECONDS:
      return {'flags': DEFAULT_FLAGS}

    try:
      InitBazelConfig()
      LoadCompilationDatabase()
    except Exception as e:
      LAST_INIT_FAILURE_TIME = time.clock()
      return {'flags': DEFAULT_FLAGS}

  filename = str(os.path.realpath(filename))
  if filename not in COMPILATION_DATABASE:
    filename = FindAlternateFile(filename)

  if filename not in COMPILATION_DATABASE:
    return {'flags': DEFAULT_FLAGS}

  result_dict = COMPILATION_DATABASE[filename]
  return {
      'flags':
          PrepareCompileFlags(result_dict['command'], result_dict['directory'])
  }


# For testing.
if __name__ == '__main__':
  import sys
  print FlagsForFile(sys.argv[1])
