#!/usr/bin/env python
# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Test for TranslationUnitGenerator tool."""

import difflib
import glob
import json
import ntpath
import os
import os.path
import subprocess
import sys


def _GenerateCompileCommands(template_path, test_files_dir):
  """Returns a JSON string containing a compilation database for the input."""
  with open(template_path) as fh:
    return fh.read().replace('$test_files_dir', test_files_dir)


def _NumberOfTestsToString(tests):
  """Returns an English sentence describing the number of tests."""
  return "%d test%s" % (tests, 's' if tests != 1 else '')


# Before running this test script, please build the translation_unit clang tool
# first. This is explained here:
# https://chromium.googlesource.com/chromium/src/+/master/docs/clang_tool_refactoring.md
def main():
  tools_clang_directory = os.path.dirname(os.path.dirname(
      os.path.realpath(__file__)))
  tools_clang_scripts_directory = os.path.join(tools_clang_directory, 'scripts')
  test_directory_for_tool = os.path.join(
      tools_clang_directory, 'translation_unit', 'test_files')
  compile_database = os.path.join(test_directory_for_tool,
                                  'compile_commands.json')
  compile_database_template = compile_database + '.template'
  source_files = glob.glob(os.path.join(test_directory_for_tool, '*.cc'))

  # Generate a temporary compilation database to run the tool over.
  with open(compile_database, 'w') as f:
    f.write(_GenerateCompileCommands(compile_database_template,
                                     test_directory_for_tool))

  args = ['python',
          os.path.join(tools_clang_scripts_directory, 'run_tool.py'),
          'translation_unit',
          test_directory_for_tool]
  args.extend(source_files)
  run_tool = subprocess.Popen(args, stdout=subprocess.PIPE)
  stdout, _ = run_tool.communicate()
  if run_tool.returncode != 0:
    print 'run_tool failed:\n%s' % stdout
    sys.exit(1)

  passed = 0
  failed = 0
  for actual in source_files:
    actual += '.filepaths'
    expected = actual + '.expected'
    print '[ RUN      ] %s' % os.path.relpath(actual)
    expected_output = actual_output = None
    with open(expected, 'r') as f:
      expected_output = f.readlines()
    with open(actual, 'r') as f:
      actual_output = f.readlines()
    has_same_filepaths = True
    for expected_line, actual_line in zip(expected_output, actual_output):
      if '//' in actual_line:
        actual_line = '//' + actual_line.split('//')[1]

      if ntpath.basename(expected_line) != ntpath.basename(actual_line):
        sys.stdout.write('expected: %s' % ntpath.basename(expected_line))
        sys.stdout.write('actual: %s' % ntpath.basename(actual_line))
        has_same_filepaths = False
        break
    if not has_same_filepaths:
      failed += 1
      for line in difflib.unified_diff(expected_output, actual_output,
                                       fromfile=os.path.relpath(expected),
                                       tofile=os.path.relpath(actual)):
        sys.stdout.write(line)
      print '[  FAILED  ] %s' % os.path.relpath(actual)
      # Don't clean up the file on failure, so the results can be referenced
      # more easily.
      continue
    print '[       OK ] %s' % os.path.relpath(actual)
    passed += 1
    os.remove(actual)

  if failed == 0:
    os.remove(compile_database)

  print '[==========] %s ran.' % _NumberOfTestsToString(len(source_files))
  if passed > 0:
    print '[  PASSED  ] %s.' % _NumberOfTestsToString(passed)
  if failed > 0:
    print '[  FAILED  ] %s.' % _NumberOfTestsToString(failed)


if __name__ == '__main__':
  sys.exit(main())
