#!/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.

// Find the newest commit that has a full set of results on the bots.

// @dart = 2.9

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

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

void main(List<String> args) async {
  final parser = new ArgParser();
  parser.addMultiOption("bot",
      abbr: "b",
      help: "Select the bots matching the glob pattern [option is repeatable]",
      splitCommas: false);
  parser.addOption("branch",
      abbr: "B",
      help: "Select the bots building this branch",
      defaultsTo: "master");
  parser.addOption("count",
      abbr: "c", help: "List this many commits", defaultsTo: "1");
  parser.addFlag("help", help: "Show the program usage.", negatable: false);

  final options = parser.parse(args);
  if (options["help"]) {
    print("""
Usage: find_base_commit.dart [OPTION]...
Find the newest commit that has a full set of results on the bots.

The options are as follows:

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

  int count = int.parse(options["count"]);
  final globs = new List<Glob>.from(
      options["bot"].map((String pattern) => new Glob(pattern)));

  // Download the most recent builds from buildbucket.
  int maxBuilds = 1000;
  final url = Uri.parse(
      "https://cr-buildbucket.appspot.com/_ah/api/buildbucket/v1/search"
      "?bucket=luci.dart.ci.sandbox"
      "&max_builds=$maxBuilds"
      "&status=COMPLETED"
      "&fields=builds(url%2Cparameters_json)");
  const maxRetries = 3;
  const timeout = const Duration(seconds: 30);
  Map<String, dynamic> object;
  for (int i = 1; i <= maxRetries; i++) {
    try {
      final client = new HttpClient();
      final request = await client.getUrl(url).timeout(timeout);
      final response = await request.close().timeout(timeout);
      object = await response
          .cast<List<int>>()
          .transform(new Utf8Decoder())
          .transform(new JsonDecoder())
          .first
          .timeout(timeout);
      client.close();
      break;
    } on TimeoutException catch (e) {
      final inSeconds = e.duration.inSeconds;
      stderr.writeln(
          "Attempt $i of $maxRetries timed out after $inSeconds seconds");
      if (i == maxRetries) {
        stderr.writeln("error: Failed to download $url");
        exit(1);
      }
    }
  }

  // Locate the builds we're interested in and map them to each commit. The
  // builds returned by the API are sorted with the newest first. Since bots
  // don't build back in time and always build the latest commit whenever they
  // can, the first time we see a commit, we know it's newer than all commits
  // we haven't seen yet. The insertion order into the botsForCommits map will
  // then sorted with the newest commit first.
  final builds = object["builds"];
  final botsForCommits = <String, Set<String>>{};
  for (final build in builds) {
    final parameters = jsonDecode(build["parameters_json"]);
    final bot = parameters["builder_name"];
    if (bot.endsWith("-beta") ||
        bot.endsWith("-dev") ||
        bot.endsWith("-stable")) {
      // Ignore the release builders. The -try builders aren't in the
      // bucket we're reading.
      continue;
    }
    if (globs.isNotEmpty && !globs.any((glob) => glob.matches(bot))) {
      // Filter way bots we're not interested in.
      continue;
    }
    final properties = parameters["properties"];
    final branch = properties["branch"];
    if (branch != null && branch != "refs/heads/${options['branch']}") {
      // Ignore bots that are building the wrong branch.
      continue;
    }
    final commit = properties["revision"];
    if (commit == null) {
      // Ignore bots that aren't commit based, e.g. fuzz-linux.
      continue;
    }
    final botsForCommit =
        botsForCommits.putIfAbsent(commit, () => new Set<String>());
    botsForCommit.add(bot);
  }

  if (botsForCommits.isEmpty) {
    print("Failed to locate any commits having run on the bots");
    exitCode = 1;
    return;
  }

  int maxBots = 0;
  for (final commit in botsForCommits.keys) {
    maxBots = max(maxBots, botsForCommits[commit].length);
  }

  // List commits run on the most bots.
  for (final commit in botsForCommits.keys
      .where((commit) => botsForCommits[commit].length == maxBots)
      .take(count)) {
    print(commit);
  }
}
