#!/usr/bin/env python
#
#=- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python  -*-=#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
#===------------------------------------------------------------------------===#

"""
Parallel find-all-symbols runner
================================

Runs find-all-symbols over all files in a compilation database.

Example invocations.
- Run find-all-symbols on all files in the current working directory.
    run-find-all-symbols.py <source-file>

Compilation database setup:
http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
"""

import argparse
import json
import multiprocessing
import os
import Queue
import shutil
import subprocess
import sys
import tempfile
import threading


def find_compilation_database(path):
  """Adjusts the directory until a compilation database is found."""
  result = './'
  while not os.path.isfile(os.path.join(result, path)):
    if os.path.realpath(result) == '/':
      print('Error: could not find compilation database.')
      sys.exit(1)
    result += '../'
  return os.path.realpath(result)


def MergeSymbols(directory, args):
  """Merge all symbol files (yaml) in a given directory into a single file."""
  invocation = [args.binary, '-merge-dir='+directory, args.saving_path]
  subprocess.call(invocation)
  print('Merge is finished. Saving results in ' + args.saving_path)


def run_find_all_symbols(args, tmpdir, build_path, queue):
  """Takes filenames out of queue and runs find-all-symbols on them."""
  while True:
    name = queue.get()
    invocation = [args.binary, name, '-output-dir='+tmpdir, '-p='+build_path]
    sys.stdout.write(' '.join(invocation) + '\n')
    subprocess.call(invocation)
    queue.task_done()


def main():
  parser = argparse.ArgumentParser(description='Runs find-all-symbols over all'
                                   'files in a compilation database.')
  parser.add_argument('-binary', metavar='PATH',
                      default='./bin/find-all-symbols',
                      help='path to find-all-symbols binary')
  parser.add_argument('-j', type=int, default=0,
                      help='number of instances to be run in parallel.')
  parser.add_argument('-p', dest='build_path',
                      help='path used to read a compilation database.')
  parser.add_argument('-saving-path', default='./find_all_symbols_db.yaml',
                      help='result saving path')
  args = parser.parse_args()

  db_path = 'compile_commands.json'

  if args.build_path is not None:
    build_path = args.build_path
  else:
    build_path = find_compilation_database(db_path)

  tmpdir = tempfile.mkdtemp()

  # Load the database and extract all files.
  database = json.load(open(os.path.join(build_path, db_path)))
  files = [entry['file'] for entry in database]

  # Filter out .rc files on Windows. CMake includes them for some reason.
  files = [f for f in files if not f.endswith('.rc')]

  max_task = args.j
  if max_task == 0:
    max_task = multiprocessing.cpu_count()

  try:
    # Spin up a bunch of tidy-launching threads.
    queue = Queue.Queue(max_task)
    for _ in range(max_task):
      t = threading.Thread(target=run_find_all_symbols,
                           args=(args, tmpdir, build_path, queue))
      t.daemon = True
      t.start()

    # Fill the queue with files.
    for name in files:
      queue.put(name)

    # Wait for all threads to be done.
    queue.join()

    MergeSymbols(tmpdir, args)


  except KeyboardInterrupt:
    # This is a sad hack. Unfortunately subprocess goes
    # bonkers with ctrl-c and we start forking merrily.
    print('\nCtrl-C detected, goodbye.')
    os.kill(0, 9)


if __name__ == '__main__':
  main()
