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

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 = ArgParser();
  parser.addMultiOption("builder",
      abbr: "b",
      help: "Select the builders matching the glob [option is repeatable]",
      splitCommas: false);
  parser.addOption("branch",
      abbr: "B",
      help: "Select the builders building this branch",
      defaultsTo: "main");
  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 builders.

The options are as follows:

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

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

  // Download the most recent builds from buildbucket.
  const maxBuilds = 1000;
  final url = Uri.parse("https://cr-buildbucket.appspot.com"
      "/prpc/buildbucket.v2.Builds/SearchBuilds");
  const maxRetries = 3;
  const timeout = Duration(seconds: 30);
  final query = jsonEncode({
    "predicate": {
      "builder": {"project": "dart", "bucket": "ci.sandbox"},
      "status": "ENDED_MASK"
    },
    "pageSize": maxBuilds,
    "fields": "builds.*.builder.builder,builds.*.input"
  });
  late Map<String, dynamic> searchResult;
  for (int i = 1; i <= maxRetries; i++) {
    try {
      final client = HttpClient();
      final request = await client.postUrl(url).timeout(timeout)
        ..headers.contentType = ContentType.json
        ..headers.add(HttpHeaders.acceptHeader, ContentType.json)
        ..write(query);
      final response = await request.close().timeout(timeout);
      if (response.statusCode != 200) {
        print("Failed to search for builds: "
            "${response.statusCode}:${response.reasonPhrase}");
        exit(1);
      }
      const prefix = ")]}'";
      searchResult = await (response
          .cast<List<int>>()
          .transform(Utf8Decoder())
          .map((event) =>
              event.startsWith(prefix) ? event.substring(prefix.length) : event)
          .transform(JsonDecoder())
          .cast<Map<String, dynamic>>()
          .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 builders
  // 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 buildersForCommits map
  // will then sorted with the newest commit first.
  final builds = searchResult["builds"];
  if (builds == null) {
    print("No builds found");
    exit(1);
  }
  final buildersForCommits = <String, Set<String>>{};
  for (final build in builds) {
    final builder = build["builder"]?["builder"];
    if (builder is! String ||
        builder.endsWith("-beta") ||
        builder.endsWith("-dev") ||
        builder.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(builder))) {
      // Filter way builders we're not interested in.
      continue;
    }
    final input = build["input"]?["gitilesCommit"];
    if (input == null) {
      // Ignore builds not triggered by a commit, e.g. fuzz-linux.
      continue;
    }
    final ref = input["ref"];
    if (ref != "refs/heads/${options['branch']}") {
      // Ignore builds on the wrong branch.
      continue;
    }
    final commit = input["id"] as String;
    final buildersForCommit =
        buildersForCommits.putIfAbsent(commit, () => <String>{});
    buildersForCommit.add(builder);
  }

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

  int maxBots = 0;
  for (final builders in buildersForCommits.values) {
    maxBots = max(maxBots, builders.length);
  }

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