#!/usr/bin/env dart
// Copyright (c) 2018, 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.

/// List tests whose results are different from the previously approved results,
/// and ask whether to update the currently approved results, turning the bots
/// green.

import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'dart:math';

import 'package:args/args.dart';
import 'package:glob/glob.dart';

import 'bots/results.dart';

/// Returns whether two decoded JSON objects are identical.
bool isIdenticalJson(dynamic a, dynamic b) {
  if (a is Map<String, dynamic> && b is Map<String, dynamic>) {
    if (a.length != b.length) return false;
    for (final key in a.keys) {
      if (!b.containsKey(key)) return false;
      if (!isIdenticalJson(a[key], b[key])) return false;
    }
    return true;
  } else if (a is List<dynamic> && b is List<dynamic>) {
    if (a.length != b.length) return false;
    for (int i = 0; i < a.length; i++) {
      if (!isIdenticalJson(a[i], b[i])) return false;
    }
    return true;
  } else {
    return a == b;
  }
}

/// Returns whether two sets of approvals are identical.
bool isIdenticalApprovals(
    Map<String, Map<String, dynamic>> a, Map<String, Map<String, dynamic>> b) {
  if (a.length != b.length) return false;
  for (final key in a.keys) {
    if (!b.containsKey(key)) return false;
    if (!isIdenticalJson(a[key], b[key])) return false;
  }
  return true;
}

/// The bot names and named configurations are highly redundant if both are
/// listed. This function returns a simplified named configuration that doesn't
/// contain any aspects that's part of the bots name. This is used to get a more
/// compact and readable output.
String simplifyNamedConfiguration(String bot, String namedConfiguration) {
  final botComponents = new Set<String>.from(bot.split("-"));
  return namedConfiguration
      .split("-")
      .where((component) => !botComponents.contains(component))
      .join("-");
}

/// Represents a test on a bot with the baseline results (if tryrun), the
/// current result, the current approved result, and flakiness data.
class Test implements Comparable {
  final String bot;
  final Map<String, dynamic> baselineData;
  final Map<String, dynamic> resultData;
  final Map<String, dynamic> approvedResultData;
  final Map<String, dynamic> flakinessData;

  Test(this.bot, this.baselineData, this.resultData, this.approvedResultData,
      this.flakinessData);

  int compareTo(Object other) {
    if (other is Test) {
      if (bot.compareTo(other.bot) < 0) return -1;
      if (other.bot.compareTo(bot) < 0) return 1;
      if (configuration.compareTo(other.configuration) < 0) return -1;
      if (other.configuration.compareTo(configuration) < 0) return 1;
      if (name.compareTo(other.name) < 0) return -1;
      if (other.name.compareTo(name) < 0) return 1;
    }
    return 0;
  }

  Map<String, dynamic> get _sharedData =>
      resultData ?? baselineData ?? approvedResultData;
  String get name => _sharedData["name"];
  String get configuration => _sharedData["configuration"];
  String get key => "$configuration:$name";
  String get expected => _sharedData["expected"];
  String get result => (resultData ?? const {})["result"];
  bool get matches => _sharedData["matches"];
  String get baselineResult => (baselineData ?? const {})["result"];
  String get approvedResult => (approvedResultData ?? const {})["result"];
  bool get isDifferent => result != null && result != baselineResult;
  bool get isApproved => result == null || result == approvedResult;
  List<String> get flakyModes =>
      flakinessData != null ? flakinessData["outcomes"].cast<String>() : null;
  bool get isFlake => flakinessData != null && flakyModes.contains(result);
}

/// Loads the results file as as a map if the file exists, otherwise returns the
/// empty map.
Future<Map<String, Map<String, dynamic>>> loadResultsMapIfExists(
        String path) async =>
    await new File(path).exists()
        ? loadResultsMap(path)
        : <String, Map<String, dynamic>>{};

/// Exception for when the results for a builder can't be found.
class NoResultsException implements Exception {
  final String message;
  final String buildUrl;

  NoResultsException(this.message, this.buildUrl);

  String toString() => message;
}

/// Loads a log from logdog.
Future<String> loadLog(String id, String step) async {
  final buildUrl = "https://ci.chromium.org/b/$id";
  final logUrl = Uri.parse("https://logs.chromium.org/"
      "logs/dart/buildbucket/cr-buildbucket.appspot.com/"
      "$id/+/steps/$step?format=raw");
  final client = new HttpClient();
  try {
    final request =
        await client.getUrl(logUrl).timeout(const Duration(seconds: 60));
    final response = await request.close().timeout(const Duration(seconds: 60));
    if (response.statusCode == HttpStatus.notFound) {
      await response.drain();
      throw new NoResultsException(
          "The log at $logUrl doesn't exist: ${response.statusCode}", buildUrl);
    }
    if (response.statusCode != HttpStatus.ok) {
      await response.drain();
      throw new Exception("Failed to download $logUrl: ${response.statusCode}");
    }
    final contents = (await response
            .cast<List<int>>()
            .transform(new Utf8Decoder())
            .timeout(const Duration(seconds: 60))
            .toList())
        .join("");
    return contents;
  } finally {
    client.close();
  }
}

/// TODO(https://github.com/dart-lang/sdk/issues/36015): The step name changed
/// incompatibly, allow both temporarily to reduce the user breakage. Remove
/// this 2019-03-25.
Future<String> todoFallbackLoadLog(
    String id, String primary, String secondary) async {
  try {
    return await loadLog(id, primary);
  } catch (e) {
    if (e.toString().startsWith("Exception: The log at ") &&
        e.toString().endsWith(" doesn't exist")) {
      return await loadLog(id, secondary);
    }
    rethrow;
  }
}

/// Loads the results from the bot.
Future<List<Test>> loadResultsFromBot(String bot, ArgResults options,
    String changeId, Map<String, dynamic> changelistBuild) async {
  if (options["verbose"]) {
    print("Loading $bot...");
  }
  // gsutil cp -r requires a destination directory, use a temporary one.
  final tmpdir = await Directory.systemTemp.createTemp("approve_results.");
  try {
    // The 'latest' file contains the name of the latest build that we
    // should download. When preapproving a changelist, we instead find out
    // which build the commit queue was rebased on.
    /// TODO(https://github.com/dart-lang/sdk/issues/36015): The step name
    /// changed incompatibly, allow both temporarily to reduce the user
    /// breakage. Remove this 2019-03-25.
    final build = (changeId != null
            ? await todoFallbackLoadLog(
                changelistBuild["id"],
                "download_previous_results/0/steps/gsutil_find_latest_build/0/logs/"
                    "raw_io.output_text_latest_/0",
                "gsutil_find_latest_build/0/logs/raw_io.output_text_latest_/0")
            : await readFile(bot, "latest"))
        .trim();

    // Asynchronously download the latest build and the current approved
    // results. Download try results from trybot try runs if preapproving.
    final tryResults = <String, Map<String, dynamic>>{};
    await Future.wait([
      cpRecursiveGsutil(buildCloudPath(bot, build), tmpdir.path),
      cpRecursiveGsutil(
          "$approvedResultsStoragePath/$bot/approved_results.json",
          "${tmpdir.path}/approved_results.json"),
      new Future(() async {
        if (changeId != null) {
          tryResults.addAll(parseResultsMap(await loadLog(
              changelistBuild["id"], "test_results/0/logs/results.json/0")));
        }
      }),
    ]);

    // Check the build was properly downloaded.
    final buildPath = "${tmpdir.path}/$build";
    final buildDirectory = new Directory(buildPath);
    if (!await buildDirectory.exists()) {
      print("$bot: Build directory didn't exist");
      return <Test>[];
    }

    // Load the run.json to find the named configuration.
    final resultsFile = new File("$buildPath/results.json");
    if (!await resultsFile.exists()) {
      print("$bot: No results.json exists");
      return <Test>[];
    }

    // Load the current results, the approved resutls, and the flakiness
    // information.
    final results = await loadResultsMapIfExists("$buildPath/results.json");
    final flaky = await loadResultsMapIfExists("$buildPath/flaky.json");
    final approvedResults =
        await loadResultsMapIfExists("${tmpdir.path}/approved_results.json");

    // TODO: Remove 2019-04-08: Discard any invalid pre-approvals made with a
    // version of approve_results between 065910f0 and a13ac1b4. Pre-approving
    // a new test could add pre-approvals with null configuration and null name.
    approvedResults.remove("null:null");

    // Construct an object for every test containing its current result,
    // what the last approved result was, and whether it's flaky.
    final tests = <Test>[];
    final testResults = changeId != null ? tryResults : results;
    for (final key in testResults.keys) {
      final baselineResult = changeId != null ? results[key] : null;
      final testResult = testResults[key];
      final approvedResult = approvedResults[key];
      final flakiness = flaky[key];
      final test =
          new Test(bot, baselineResult, testResult, approvedResult, flakiness);
      tests.add(test);
    }
    // Add in approvals whose test was no longer in the results.
    for (final key in approvedResults.keys) {
      if (testResults.containsKey(key)) continue;
      final baselineResult = changeId != null ? results[key] : null;
      final approvedResult = approvedResults[key];
      final flakiness = flaky[key];
      final test =
          new Test(bot, baselineResult, null, approvedResult, flakiness);
      tests.add(test);
    }
    if (options["verbose"]) {
      print("Loaded $bot (${tests.length} tests).");
    }
    return tests;
  } finally {
    // Always clean up the temporary directory when we don't need it.
    await tmpdir.delete(recursive: true);
  }
}

Future<Map<String, dynamic>> loadJsonPrefixedAPI(String url) async {
  final client = new HttpClient();
  try {
    final request = await client
        .getUrl(Uri.parse(url))
        .timeout(const Duration(seconds: 30));
    final response = await request.close().timeout(const Duration(seconds: 30));
    if (response.statusCode != HttpStatus.ok) {
      throw new Exception("Failed to request $url: ${response.statusCode}");
    }
    final text = await response
        .cast<List<int>>()
        .transform(utf8.decoder)
        .join()
        .timeout(const Duration(seconds: 30));
    return jsonDecode(text.substring(5 /* ")]}'\n" */));
  } finally {
    client.close();
  }
}

Future<Map<String, dynamic>> loadChangelistDetails(
    String gerritHost, String changeId) async {
  // ?O=516714 requests the revisions field.
  final url = "https://$gerritHost/changes/$changeId/detail?O=516714";
  return await loadJsonPrefixedAPI(url);
}

main(List<String> args) async {
  final parser = new ArgParser();
  parser.addFlag("automated-approver",
      help: "Record the approval as done by an automated process.",
      negatable: false);
  parser.addMultiOption("bot",
      abbr: "b",
      help: "Select the bots matching the glob pattern [option is repeatable]",
      splitCommas: false);
  parser.addFlag("help", help: "Show the program usage.", negatable: false);
  parser.addFlag("failures-only",
      help: "Approve failures only.", negatable: false);
  parser.addFlag("list",
      abbr: "l", help: "List the available bots.", negatable: false);
  parser.addFlag("no",
      abbr: "n",
      help: "Show changed results but don't approve.",
      negatable: false);
  parser.addOption("preapprove",
      abbr: "p", help: "Preapprove the new failures in a gerrit CL.");
  parser.addFlag("successes-only",
      help: "Approve successes only.", negatable: false);
  parser.addFlag("verbose",
      abbr: "v", help: "Describe asynchronous operations.", negatable: false);
  parser.addFlag("yes",
      abbr: "y", help: "Approve the results.", negatable: false);
  parser.addOption("table",
      abbr: "T",
      help: "Select table format.",
      allowed: ["markdown", "indent"],
      defaultsTo: "markdown");

  final options = parser.parse(args);
  if ((options["preapprove"] == null &&
          options["bot"].isEmpty &&
          !options["list"]) ||
      options["help"]) {
    print("""
Usage: approve_results.dart [OPTION]...
List tests whose results are different from the previously approved results, and
ask whether to update the currently approved results, turning the bots green.

See the documentation at https://goto.google.com/dart-status-file-free-workflow

The options are as follows:

${parser.usage}""");
    return;
  }

  if (options["no"] && options["yes"]) {
    stderr.writeln("The --no and --yes options are mutually incompatible");
    exitCode = 1;
    return;
  }

  if (options.rest.isNotEmpty) {
    stderr.writeln("Unexpected extra argument: ${options.rest.first}");
    exitCode = 1;
    return;
  }

  // Locate gsutil.py.
  gsutilPy =
      Platform.script.resolve("../third_party/gsutil/gsutil.py").toFilePath();

  // Load the list of bots according to the test matrix.
  final testMatrixPath =
      Platform.script.resolve("bots/test_matrix.json").toFilePath();
  final testMatrix = jsonDecode(await new File(testMatrixPath).readAsString());
  final builderConfigurations = testMatrix["builder_configurations"];
  final testMatrixBots = <String>[];
  for (final builderConfiguration in builderConfigurations) {
    final steps = builderConfiguration["steps"];
    // Only consider bots that use tools/test.py or custom test runners.
    if (!steps.any((step) =>
        step["script"] == null ||
        step["script"] == "tools/test.py" ||
        step["testRunner"] == true)) {
      continue;
    }
    final builders = builderConfiguration["builders"].cast<String>();
    testMatrixBots.addAll(builders);
  }

  // Load the list of bots that have data in cloud storage.
  if (options["verbose"]) {
    print("Loading list of bots...");
  }
  final botsWithData = (await listBots())
      .where((bot) => !bot.endsWith("-try"))
      .where((bot) => !bot.endsWith("-dev"))
      .where((bot) => !bot.endsWith("-stable"));
  if (options["verbose"]) {
    print("Loaded list of bots.");
  }

  // The currently active bots are the bots both mentioned in the test matrix
  // and that have results in cloud storage.
  final allBots = new Set<String>.from(testMatrixBots)
      .intersection(new Set<String>.from(botsWithData))
      .toList()
        ..sort();

  // List the currently active bots if requested.
  if (options["list"]) {
    for (final bot in allBots) {
      print(bot);
    }
    return;
  }

  // Determine which builders have run for the changelist.
  final changelistBuilds = <String, Map<String, dynamic>>{};
  final isPreapproval = options["preapprove"] != null;
  String changeId;
  if (isPreapproval) {
    if (options["verbose"]) {
      print("Loading changelist details...");
    }
    final gerritHost = "dart-review.googlesource.com";
    final gerritProject = "sdk";
    final prefix = "https://$gerritHost/c/$gerritProject/+/";
    final gerrit = options["preapprove"];
    if (!gerrit.startsWith(prefix)) {
      stderr.writeln("error: $gerrit doesn't start with $prefix");
      exitCode = 1;
      return;
    }
    final components = gerrit.substring(prefix.length).split("/");
    if (!((components.length == 1 && int.tryParse(components[0]) != null) ||
        (components.length == 2 &&
            int.tryParse(components[0]) != null &&
            int.tryParse(components[1]) != null))) {
      stderr.writeln("error: $gerrit must be in the form of "
          "$prefix<changelist> or $prefix<changelist>/<patchset>");
      exitCode = 1;
      return;
    }
    final changelist = int.parse(components[0]);
    final details =
        await loadChangelistDetails(gerritHost, changelist.toString());
    changeId = details["change_id"];
    final patchset = 2 <= components.length
        ? int.parse(components[1])
        : details["revisions"][details["current_revision"]]["_number"];
    if (2 <= components.length) {
      print("Using Change-Id $changeId patchset $patchset");
    } else {
      print("Using Change-Id $changeId with the latest patchset $patchset");
    }
    if (options["verbose"]) {
      print("Loading list of try runs...");
    }
    final buildset = "buildset:patch/gerrit/$gerritHost/$changelist/$patchset";

    Future<Map<String, dynamic>> searchBuilds(String cursor) async {
      final url = Uri.parse(
          "https://cr-buildbucket.appspot.com/_ah/api/buildbucket/v1/search"
          "?bucket=luci.dart.try"
          "&tag=${Uri.encodeComponent(buildset)}"
          "&fields=builds(id%2Ctags%2Cstatus%2Cstarted_ts),next_cursor"
          "&start_cursor=$cursor");
      final client = new HttpClient();
      final request =
          await client.getUrl(url).timeout(const Duration(seconds: 30));
      final response =
          await request.close().timeout(const Duration(seconds: 30));
      if (response.statusCode != HttpStatus.ok) {
        throw new Exception("Failed to request try runs for $gerrit");
      }
      final Map<String, dynamic> object = await response
          .cast<List<int>>()
          .transform(new Utf8Decoder())
          .transform(new JsonDecoder())
          .first
          .timeout(const Duration(seconds: 30));
      client.close();
      return object;
    }

    var cursor = "";
    final builds = [];
    do {
      final object = await searchBuilds(cursor);
      if (cursor.isEmpty && object["builds"] == null) {
        stderr.writeln(
            "error: $prefix$changelist has no try runs for patchset $patchset");
        exitCode = 1;
        return;
      }
      builds.addAll(object["builds"]);
      cursor = object["next_cursor"];
    } while (cursor != null);

    // Prefer the newest completed build.
    Map<String, dynamic> preferredBuild(
        Map<String, dynamic> a, Map<String, dynamic> b) {
      if (a != null && b == null) return a;
      if (a == null && b != null) return b;
      if (a != null && b != null) {
        if (a["status"] == "COMPLETED" && b["status"] != "COMPLETED") return a;
        if (a["status"] != "COMPLETED" && b["status"] == "COMPLETED") return b;
        if (a["started_ts"] == null && b["started_ts"] != null) return a;
        if (a["started_ts"] != null && b["started_ts"] == null) return b;
        if (a["started_ts"] != null && b["started_ts"] != null) {
          if (int.parse(a["started_ts"]) > int.parse(b["started_ts"])) return a;
          if (int.parse(a["started_ts"]) < int.parse(b["started_ts"])) return b;
        }
      }
      return b;
    }

    for (final build in builds) {
      final tags = (build["tags"] as List<dynamic>).cast<String>();
      final builder = tags
          .firstWhere((tag) => tag.startsWith("builder:"))
          .substring("builder:".length);
      final ciBuilder = builder.replaceFirst(new RegExp("-try\$"), "");
      if (!allBots.contains(ciBuilder)) {
        continue;
      }
      changelistBuilds[ciBuilder] =
          preferredBuild(changelistBuilds[ciBuilder], build);
    }
    if (options["verbose"]) {
      print("Loaded list of try runs.");
    }
  }
  final changelistBuilders = new Set<String>.from(changelistBuilds.keys);

  // Select all the bots matching the glob patterns,
  final finalBotList =
      options["preapprove"] != null ? changelistBuilders : allBots;
  final botPatterns = options["preapprove"] != null && options["bot"].isEmpty
      ? ["*"]
      : options["bot"];
  final bots = new Set<String>();
  for (final botPattern in botPatterns) {
    final glob = new Glob(botPattern);
    bool any = false;
    for (final bot in finalBotList) {
      if (glob.matches(bot)) {
        bots.add(bot);
        any = true;
      }
    }
    if (!any) {
      stderr.writeln("error: No bots matched pattern: $botPattern");
      stderr.writeln("Try --list to get the list of bots, or --help for help");
      exitCode = 1;
      return;
    }
  }
  for (final bot in bots) {
    print("Selected bot: $bot");
  }

  // Error out if any of the requested try runs are incomplete.
  bool anyIncomplete = false;
  for (final bot in bots) {
    if (options["preapprove"] != null &&
        changelistBuilds[bot]["status"] != "COMPLETED") {
      stderr.writeln("error: The try run for $bot isn't complete yet: " +
          changelistBuilds[bot]["status"]);
      anyIncomplete = true;
    }
  }
  if (anyIncomplete) {
    exitCode = 1;
    return;
  }

  // Load all the latest results for the selected bots, as well as flakiness
  // data, and the set of currently approved results. Each bot's latest build
  // is downloaded in parallel to make this phase faster.
  final testListFutures = <Future<List<Test>>>[];
  final noResultsBuilds = new SplayTreeMap<String, String>();
  for (final String bot in bots) {
    testListFutures.add(new Future(() async {
      try {
        return await loadResultsFromBot(
            bot, options, changeId, changelistBuilds[bot]);
      } on NoResultsException catch (e) {
        print(
            "Error: Failed to find results for $bot build <${e.buildUrl}>: $e");
        noResultsBuilds[bot] = e.buildUrl;
        return <Test>[];
      }
    }));
  }

  // Collect all the tests from the synchronous downloads.
  final tests = <Test>[];
  for (final testList in await Future.wait(testListFutures)) {
    tests.addAll(testList);
  }
  tests.sort();
  print("");

  // Compute statistics and the set of interesting tests.
  final flakyTestsCount =
      tests.where((test) => test.resultData != null && test.isFlake).length;
  final failingTestsCount = tests
      .where(
          (test) => test.resultData != null && !test.isFlake && !test.matches)
      .length;
  final differentTests = tests
      .where((test) =>
          (isPreapproval ? test.isDifferent : !test.isApproved) &&
          !test.isFlake)
      .toList();
  final selectedTests = differentTests
      .where((test) => !(test.matches
          ? options["failures-only"]
          : options["successes-only"]))
      .toList();
  final fixedTests = selectedTests.where((test) => test.matches).toList();
  final brokenTests = selectedTests.where((test) => !test.matches).toList();

  // Find out which bots have multiple configurations.
  final configurationsForBots = <String, Set<String>>{};
  for (final test in tests) {
    var configurationSet = configurationsForBots[test.bot];
    if (configurationSet == null) {
      configurationsForBots[test.bot] = configurationSet = new Set<String>();
    }
    configurationSet.add(test.configuration);
  }

  // Compute a nice displayed name for the bot and configuration. If the bot
  // only has a single configuration, then only mention the bot. Otherwise,
  // remove the redundant parts from configuration and present it compactly.
  // This is needed to avoid the tables becoming way too large.
  String getBotDisplayName(String bot, String configuration) {
    if (configurationsForBots[bot].length == 1) {
      return bot;
    } else {
      final simpleConfig = simplifyNamedConfiguration(bot, configuration);
      return "$bot/$simpleConfig";
    }
  }

  // Compute the width of the fields in the below tables.
  final unapprovedBots = new Set<String>();
  int longestBot = "BOT/CONFIG".length;
  int longestTest = "TEST".length;
  int longestResult = "RESULT".length;
  int longestExpected = "EXPECTED".length;
  for (final test in selectedTests) {
    unapprovedBots.add(test.bot);
    final botDisplayName = getBotDisplayName(test.bot, test.configuration);
    longestBot = max(longestBot, botDisplayName.length);
    longestTest = max(longestTest, test.name.length);
    longestResult = max(longestResult, test.result.length);
    longestExpected = max(longestExpected, test.expected.length);
  }
  longestTest = min(longestTest, 120); // Some tests names are extremely long.

  // Table of lists that now succeed.
  if (fixedTests.isNotEmpty) {
    print("The following tests are now succeeding:\n");
    if (options["table"] == "markdown") {
      print("| ${'BOT/CONFIG'.padRight(longestBot)} "
          "| ${'TEST'.padRight(longestTest)} |");
      print("| ${'-' * longestBot} "
          "| ${'-' * longestTest} |");
    } else if (options["table"] == "indent") {
      print("${'BOT/CONFIG'.padRight(longestBot)}  "
          "TEST");
    }
    for (final test in fixedTests) {
      final botDisplayName = getBotDisplayName(test.bot, test.configuration);
      if (options["table"] == "markdown") {
        print("| ${botDisplayName.padRight(longestBot)} "
            "| ${test.name.padRight(longestTest)} |");
      } else if (options["table"] == "indent") {
        print("${botDisplayName.padRight(longestBot)}  "
            "${test.name}");
      }
    }
    print("");
  }

  /// Table of lists that now fail.
  if (brokenTests.isNotEmpty) {
    print("The following tests are now failing:\n");
    if (options["table"] == "markdown") {
      print("| ${'BOT'.padRight(longestBot)} "
          "| ${'TEST'.padRight(longestTest)} "
          "| ${'RESULT'.padRight(longestResult)} "
          "| ${'EXPECTED'.padRight(longestExpected)} | ");
      print("| ${'-' * longestBot} "
          "| ${'-' * longestTest} "
          "| ${'-' * longestResult} "
          "| ${'-' * longestExpected} | ");
    } else if (options["table"] == "indent") {
      print("${'BOT'.padRight(longestBot)}  "
          "${'TEST'.padRight(longestTest)}  "
          "${'RESULT'.padRight(longestResult)}  "
          "EXPECTED");
    }
    for (final test in brokenTests) {
      final botDisplayName = getBotDisplayName(test.bot, test.configuration);
      if (options["table"] == "markdown") {
        print("| ${botDisplayName.padRight(longestBot)} "
            "| ${test.name.padRight(longestTest)} "
            "| ${test.result.padRight(longestResult)} "
            "| ${test.expected.padRight(longestExpected)} |");
      } else if (options["table"] == "indent") {
        print("${botDisplayName.padRight(longestBot)}  "
            "${test.name.padRight(longestTest)}  "
            "${test.result.padRight(longestResult)}  "
            "${test.expected}");
      }
    }
    print("");
  }

  // Provide statistics on how well the bots are doing.
  void statistic(int numerator, int denominator, String what) {
    double percent = numerator / denominator * 100.0;
    String percentString = percent.toStringAsFixed(2) + "%";
    print("$numerator of $denominator $what ($percentString)");
  }

  statistic(failingTestsCount, tests.length, "tests are failing");
  statistic(flakyTestsCount, tests.length, "tests are flaky");
  statistic(
      fixedTests.length, tests.length, "tests were fixed since last approval");
  statistic(brokenTests.length, tests.length,
      "tests were broken since last approval");

  // Warn about any builders where results weren't available.
  if (noResultsBuilds.isNotEmpty) {
    print("");
    noResultsBuilds.forEach((String builder, String buildUrl) {
      print("Warning: No results were found for $builder: <$buildUrl>");
    });
    print("Warning: Builders without results are usually due to infrastructure "
        "issues, please have a closer look at the affected builders and try "
        "the build again.");
  }

  // Stop if there's nothing to do.
  if (unapprovedBots.isEmpty) {
    print("\nEvery test result has already been approved.");
    return;
  }

  // Stop if this is a dry run.
  if (options["no"]) {
    if (selectedTests.length == 1) {
      print("1 test has a changed result and needs approval");
    } else {
      print("${selectedTests.length} "
          "tests have changed results and need approval");
    }
    return;
  }

  // Confirm the approval if run interactively.
  if (!options["yes"]) {
    print("");
    print("Note: It is assumed bugs have been filed about the above failures "
        "before they are approved here.");
    if (brokenTests.isNotEmpty) {
      final builderPlural = bots.length == 1 ? "builder" : "builders";
      final tryBuilders = isPreapproval ? "try$builderPlural" : builderPlural;
      final tryCommit = isPreapproval ? "tryrun" : "commit";
      print("Note: Approving the failures will turn the "
          "$tryBuilders green on the next $tryCommit.");
    }
    while (true) {
      final approve = isPreapproval ? "pre-approve" : "approve";
      stdout.write("Do you want to $approve? (yes/no) [yes] ");
      final line = stdin.readLineSync();
      // End of file condition is considered no.
      if (line == null) {
        print("n");
        return;
      }
      if (line.toLowerCase() == "n" || line.toLowerCase() == "no") {
        return;
      }
      if (line == "" ||
          line.toLowerCase() == "y" ||
          line.toLowerCase() == "yes") {
        break;
      }
    }
  } else {
    print("Note: It is assumed bugs have been filed about the above failures.");
  }
  print("");

  // Log who approved these results.
  final username =
      (options["automated-approver"] ? "automatic-approval" : null) ??
          Platform.environment["LOGNAME"] ??
          Platform.environment["USER"] ??
          Platform.environment["USERNAME"];
  if (username == null || username == "") {
    stderr.writeln("error: Your identity could not be established. "
        "Please set one of the LOGNAME, USER, USERNAME environment variables.");
    exitCode = 1;
    return;
  }
  final nowDate = new DateTime.now().toUtc();
  final now = nowDate.toIso8601String();

  // Deep clones a decoded json object.
  dynamic deepClone(dynamic object) {
    if (object is Map<String, dynamic>) {
      final result = <String, dynamic>{};
      for (final key in object.keys) {
        result[key] = deepClone(object[key]);
      }
      return result;
    } else if (object is List<dynamic>) {
      final result = <dynamic>[];
      for (final value in object) {
        result.add(deepClone(value));
      }
      return result;
    } else {
      return object;
    }
  }

  // Build the new approval data with the changes in test results applied.
  final newApprovalsForBuilders = <String, Map<String, Map<String, dynamic>>>{};

  if (isPreapproval) {
    // Import all the existing approval data, keeping tests that don't exist
    // anymore.
    for (final test in tests) {
      if (test.approvedResultData == null) continue;
      final approvalData = deepClone(test.approvedResultData);
      // TODO(https://github.com/dart-lang/sdk/issues/36279): Remove needless
      // fields that shouldn't be in the approvals data. Remove this 2019-04-03.
      approvalData.remove("bot_name");
      approvalData.remove("builder_name");
      approvalData.remove("build_number");
      approvalData.remove("changed");
      approvalData.remove("commit_hash");
      approvalData.remove("commit_time");
      approvalData.remove("commit_hash");
      approvalData.remove("flaky");
      approvalData.remove("previous_build_number");
      approvalData.remove("previous_commit_hash");
      approvalData.remove("previous_commit_time");
      approvalData.remove("previous_flaky");
      approvalData.remove("previous_result");
      approvalData.remove("time_ms");
      // Discard all the existing pre-approvals for this changelist.
      final preapprovals =
          approvalData.putIfAbsent("preapprovals", () => <String, dynamic>{});
      preapprovals.remove(changeId);
      final newApprovals = newApprovalsForBuilders.putIfAbsent(
          test.bot, () => new SplayTreeMap<String, Map<String, dynamic>>());
      newApprovals[test.key] = approvalData;
    }

    // Pre-approve all the regressions (no need to pre-approve fixed tests).
    for (final test in brokenTests) {
      final newApprovals = newApprovalsForBuilders.putIfAbsent(
          test.bot, () => new SplayTreeMap<String, Map<String, dynamic>>());
      final approvalData =
          newApprovals.putIfAbsent(test.key, () => <String, dynamic>{});
      approvalData["name"] = test.name;
      approvalData["configuration"] = test.configuration;
      approvalData["suite"] = test.resultData["suite"];
      approvalData["test_name"] = test.resultData["test_name"];
      final preapprovals =
          approvalData.putIfAbsent("preapprovals", () => <String, dynamic>{});
      final preapproval =
          preapprovals.putIfAbsent(changeId, () => <String, dynamic>{});
      preapproval["from"] = test.approvedResult;
      preapproval["result"] = test.result;
      preapproval["matches"] = test.matches;
      preapproval["expected"] = test.expected;
      preapproval["preapprover"] = username;
      preapproval["preapproved_at"] = now;
      preapproval["expires"] =
          nowDate.add(const Duration(days: 30)).toIso8601String();
    }
  } else {
    // Import all the existing approval data for tests, removing tests that
    // don't exist anymore unless they have pre-approvals.
    for (final test in tests) {
      if (test.approvedResultData == null) continue;
      if (test.result == null &&
          (test.approvedResultData["preapprovals"] ?? <dynamic>[]).isEmpty) {
        continue;
      }
      final approvalData = deepClone(test.approvedResultData);
      // TODO(https://github.com/dart-lang/sdk/issues/36279): Remove needless
      // fields that shouldn't be in the approvals data. Remove this 2019-04-03.
      approvalData.remove("bot_name");
      approvalData.remove("builder_name");
      approvalData.remove("build_number");
      approvalData.remove("changed");
      approvalData.remove("commit_hash");
      approvalData.remove("commit_time");
      approvalData.remove("commit_hash");
      approvalData.remove("flaky");
      approvalData.remove("previous_build_number");
      approvalData.remove("previous_commit_hash");
      approvalData.remove("previous_commit_time");
      approvalData.remove("previous_flaky");
      approvalData.remove("previous_result");
      approvalData.remove("time_ms");
      approvalData.putIfAbsent("preapprovals", () => <String, dynamic>{});
      final newApprovals = newApprovalsForBuilders.putIfAbsent(
          test.bot, () => new SplayTreeMap<String, Map<String, dynamic>>());
      newApprovals[test.key] = approvalData;
    }

    // Approve the changes in test results.
    for (final test in selectedTests) {
      final newApprovals = newApprovalsForBuilders.putIfAbsent(
          test.bot, () => new SplayTreeMap<String, Map<String, dynamic>>());
      final approvalData =
          newApprovals.putIfAbsent(test.key, () => <String, dynamic>{});
      approvalData["name"] = test.name;
      approvalData["configuration"] = test.configuration;
      approvalData["suite"] = test.resultData["suite"];
      approvalData["test_name"] = test.resultData["test_name"];
      approvalData["result"] = test.result;
      approvalData["expected"] = test.expected;
      approvalData["matches"] = test.matches;
      approvalData["approver"] = username;
      approvalData["approved_at"] = now;
      approvalData.putIfAbsent("preapprovals", () => <String, dynamic>{});
    }
  }

  // Reconstruct the old approvals so we can double check there was no race
  // condition when uploading.
  final oldApprovalsForBuilders = <String, Map<String, Map<String, dynamic>>>{};
  for (final test in tests) {
    if (test.approvedResultData == null) continue;
    final oldApprovals = oldApprovalsForBuilders.putIfAbsent(
        test.bot, () => new SplayTreeMap<String, Map<String, dynamic>>());
    oldApprovals[test.key] = test.approvedResultData;
  }
  for (final builder in newApprovalsForBuilders.keys) {
    oldApprovalsForBuilders.putIfAbsent(
        builder, () => <String, Map<String, dynamic>>{});
  }

  // Update approved_results.json for each builder with unapproved changes.
  final outDirectory =
      await Directory.systemTemp.createTemp("approved_results.");
  bool raceCondition = false;
  try {
    print("Uploading approved results...");
    final futures = <Future>[];
    for (final String builder in newApprovalsForBuilders.keys) {
      final approvals = newApprovalsForBuilders[builder].values;
      final localPath = "${outDirectory.path}/$builder.json";
      await new File(localPath).writeAsString(
          approvals.map((approval) => jsonEncode(approval) + "\n").join(""));
      final remotePath =
          "$approvedResultsStoragePath/$builder/approved_results.json";
      futures.add(new Future(() async {
        if (!options["yes"]) {
          if (options["verbose"]) {
            print("Checking for race condition on $builder...");
          }
          final oldApprovedResults = oldApprovalsForBuilders[builder];
          final oldApprovalPath = "${outDirectory.path}/$builder.json.old";
          await cpGsutil(remotePath, oldApprovalPath);
          final checkApprovedResults =
              await loadResultsMapIfExists(oldApprovalPath);
          if (!isIdenticalApprovals(oldApprovedResults, checkApprovedResults)) {
            print("error: Race condition: "
                "$builder approvals have changed, please try again.");
            raceCondition = true;
            return;
          }
        }
        if (options["verbose"]) {
          print("Uploading approved results for $builder...");
        }
        await cpGsutil(localPath, remotePath);
        print("Uploaded approved results for $builder");
      }));
    }
    await Future.wait(futures);
    if (raceCondition) {
      exitCode = 1;
      print("error: Somebody else has approved, please try again");
      return;
    }
    if (brokenTests.isNotEmpty) {
      final approved = isPreapproval ? "pre-approved" : "approved";
      final commit = isPreapproval ? "tryrun" : "commit";
      print("Successfully $approved results, the next $commit "
          "will turn builders green");
    } else {
      print("Successfully approved results");
    }
  } finally {
    await outDirectory.delete(recursive: true);
  }
}
