// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Add fields with data about the test run and the commit tested, and
// with the result on the last build tested, to the test results file.

import 'dart:convert';
import 'dart:io';

import 'package:test_runner/bot_results.dart';

const skipped = 'skipped';

void main(List<String> args) async {
  final resultsPath = args[0];
  final priorResultsPath = args[1];
  final flakyPath = args[2];
  final priorFlakyPath = args[3];
  final builderName = args[4];
  final buildNumber = args[5];
  final commitTime = int.parse(args[6]);
  final commitHash = args[7];
  final newResultsPath = args[8];
  // Load the input and the flakiness data if specified.
  final results = await loadResultsMap(resultsPath);
  final priorResults = await loadResultsMap(priorResultsPath);
  final flakes = await loadResultsMap(flakyPath);
  final priorFlakes = await loadResultsMap(priorFlakyPath);
  final firstPriorResult =
      priorResults.isEmpty ? null : priorResults.values.first;

  priorResults.forEach((key, priorResult) {
    if (priorResult['result'] != skipped) {
      results.putIfAbsent(key, () => constructNotRunResult(priorResult));
    }
  });
  for (final String key in results.keys) {
    final Map<String, dynamic> result = results[key]!;
    final Map<String, dynamic>? priorResult = priorResults[key];
    final Map<String, dynamic>? flaky = flakes[key];
    final Map<String, dynamic>? priorFlaky = priorFlakes[key];
    result['commit_hash'] = commitHash;
    result['commit_time'] = commitTime;
    result['build_number'] = buildNumber;
    result['builder_name'] = builderName;
    result['flaky'] = flaky != null && (flaky['active'] ?? true) == true;
    result['previous_flaky'] =
        priorFlaky != null && (priorFlaky['active'] ?? true) == true;
    if (firstPriorResult != null) {
      result['previous_commit_hash'] = firstPriorResult['commit_hash'];
      result['previous_commit_time'] = firstPriorResult['commit_time'];
      result['previous_build_number'] = firstPriorResult['build_number'];
    }
    if (priorResult != null) {
      result['previous_result'] = priorResult['result'];
      result['changed'] = !(result['result'] == result['previous_result'] &&
          result['flaky'] == result['previous_flaky'] &&
          result['expected'] == priorResult['expected']);
    } else {
      result['changed'] = true;
    }
  }
  final sink = File(newResultsPath).openWrite();
  final sorted = results.keys.toList()..sort();
  for (final key in sorted) {
    sink.writeln(jsonEncode(results[key]));
  }
  sink.close();
}

Map<String, dynamic> constructNotRunResult(Map<String, dynamic> previous) => {
      for (final key in [
        'name',
        'configuration',
        'suite',
        'test_name',
        'expected'
      ])
        key: previous[key],
      'time_ms': 0,
      'result': skipped,
      'matches': true,
      'bot_name': '',
    };
