#!/usr/bin/env python3
# Copyright 2017 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import os
import sys

import six

import merge_api
import results_merger


def StandardIsolatedScriptMerge(output_json, summary_json, jsons_to_merge):
  """Merge the contents of one or more results JSONs into a single JSON.

  Args:
    output_json: A path to a JSON file to which the merged results should be
      written.
    jsons_to_merge: A list of paths to JSON files that should be merged.
  """
  # summary.json is produced by swarming client itself. We are mostly interested
  # in the number of shards.
  try:
    with open(summary_json) as f:
      summary = json.load(f)
  except (IOError, ValueError):
    print(('summary.json is missing or can not be read',
           'Something is seriously wrong with swarming client or the bot.'),
          file=sys.stderr)
    return 1

  missing_shards = []
  shard_results_list = []
  for index, result in enumerate(summary['shards']):
    output_path = None
    if result:
      output_path = find_shard_output_path(index, result.get('task_id'),
                                           jsons_to_merge)
    if not output_path:
      missing_shards.append(index)
      continue

    with open(output_path) as f:
      try:
        json_contents = json.load(f)
      except ValueError as e:
        six.raise_from(ValueError('Failed to parse JSON from %s' % output_path),
                       e)
      shard_results_list.append(json_contents)

  merged_results = results_merger.merge_test_results(shard_results_list)
  if missing_shards:
    merged_results['missing_shards'] = missing_shards
    if 'global_tags' not in merged_results:
      merged_results['global_tags'] = []
    merged_results['global_tags'].append('UNRELIABLE_RESULTS')

  with open(output_json, 'w') as f:
    json.dump(merged_results, f)

  return 0


def find_shard_output_path(index, task_id, jsons_to_merge):
  """Finds the shard matching the index/task-id.

  Args:
    index: The index of the shard to load data for, this is for old api.
    task_id: The directory of the shard to load data for, this is for new api.
    jsons_to_merge: A container of file paths for shards that emitted output.

  Returns:
    * The matching path, or None
  """
  # 'output.json' is set in swarming/api.py, gtest_task method.
  matching_json_files = [
      j for j in jsons_to_merge if (os.path.basename(j) == 'output.json' and (
          os.path.basename(os.path.dirname(j)) == str(index)
          or os.path.basename(os.path.dirname(j)) == task_id))
  ]

  if not matching_json_files:
    print('shard %s test output missing' % index, file=sys.stderr)
    return None
  if len(matching_json_files) > 1:
    print('duplicate test output for shard %s' % index, file=sys.stderr)
    return None

  return matching_json_files[0]


def main(raw_args):
  parser = merge_api.ArgumentParser()
  args = parser.parse_args(raw_args)
  return StandardIsolatedScriptMerge(args.output_json, args.summary_json,
                                     args.jsons_to_merge)


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
