import time
import json


def WriteResultToJSONFile(test_suites, results, json_path):
  """Aggregate a list of unittest result object and write to a file as a JSON.

  This takes a list of result object from one or more runs (for retry purpose)
  of Python unittest tests; aggregates the list by appending each test result
  from each run and writes to a file in the correct format
  for the --isolated-script-test-output argument passed to test isolates.

  Args:
    test_suites: a list of unittest.TestSuite that were run to get
                 the list of result object; each test_suite contains
                 the tests run and is iterated to get all test cases ran.
    results: a list of unittest.TextTestResult object returned
             from running unittest tests.
    json_path: desired path to JSON file of result.
  """
  output = {
      'interrupted': False,
      'num_failures_by_type': {},
      'path_delimiter': '.',
      'seconds_since_epoch': time.time(),
      'tests': {},
      'version': 3,
  }

  def initialize(test_suite):
    for test in test_suite:
      if test.id() not in output['tests']:
        output['tests'][test.id()] = {
            'expected': 'PASS',
            'actual': []
        }

  for test_suite in test_suites:
    initialize(test_suite)

  def get_pass_fail(test_suite, result):
    success = []
    fail = []
    for failure in result.failures + result.errors:
      fail.append(failure[0].id())
    for test in test_suite:
      if test.id() not in fail:
        success.append(test.id())
    return {
        'success': success,
        'fail': fail,
    }

  for test_suite, result in zip(test_suites, results):
    pass_fail = get_pass_fail(test_suite, result)
    for s in pass_fail['success']:
      output['tests'][s]['actual'].append('PASS')
    for f in pass_fail['fail']:
      output['tests'][f]['actual'].append('FAIL')

  num_fails = 0
  for test_result in output['tests'].itervalues():
    if test_result['actual'][-1] == 'FAIL':
      num_fails += 1
      test_result['is_unexpected'] = True
    test_result['actual'] = ' '.join(test_result['actual'])

  output['num_failures_by_type']['FAIL'] = num_fails
  output['num_failures_by_type']['PASS'] = len(output['tests']) - num_fails

  with open(json_path, 'w') as script_out_file:
    json.dump(output, script_out_file)
    script_out_file.write('\n')