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

// A script to find all try jobs for a set of tests.
//
// Usage:
//
// ```
// $ tools/find_builders.dart ffi/regress_51504_test ffi/regress_52298_test
// Cq-Include-Trybots: dart/try:vm-kernel-linux-debug-x64,...
// ```

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

// TODO(dacoharkes): Be able to use test full paths instead of test names.
// TODO(dacoharkes): Be able to use different filters.
Future<void> main(List<String> args) async {
  if (args.contains('--help')) {
    return printHelp();
  }
  final testNames = args;

  final configurations = _filterConfigurations({
    for (final testName in testNames) ...await _testGetConfigurations(testName),
  });
  final configurationBuilders = await _configurationBuilders();
  final builders = _filterBuilders({
    for (final config in configurations) configurationBuilders[config]!,
  }).toList()
    ..sort();

  final gerritTryList = builders.map((b) => '$b-try').join(',');
  print('Cq-Include-Trybots: dart/try:$gerritTryList');
}

Future<List<String>> _testGetConfigurations(String testName) async {
  final requestUrl = Uri(
    scheme: 'https',
    host: 'current-results-qvyo5rktwa-uc.a.run.app',
    path: 'v1/results',
    queryParameters: {'filter': testName},
  );
  final response = await _get(requestUrl);
  final object = jsonDecode(response) as Map<String, dynamic>;
  return [
    for (final result in ((object['results'] as List)).cast<Map>())
      result['configuration'],
  ];
}

Future<String> _get(Uri requestUrl) async {
  final client = HttpClient();
  final request = await client.getUrl(requestUrl);
  final response = await request.close();
  final responseString = await response.transform(const Utf8Decoder()).join();
  client.close();
  return responseString;
}

Iterable<String> _filterConfigurations(Set<String> configs) {
  final result = <String>[];
  for (final config in configs) {
    if (config.contains('debug')) {
      result.add(config);
    } else if (config.contains('release') &&
        !configs.contains(config.replaceFirst('release', 'debug'))) {
      result.add(config);
    } else if (config.contains('profile') &&
        !configs.contains(config.replaceFirst('profile', 'debug')) &&
        !configs.contains(config.replaceFirst('profile', 'release'))) {
      result.add(config);
    }
  }
  return result..sort();
}

Iterable<String> _filterBuilders(Iterable<String> builders) {
  return builders.where(
    (b) => !_ciOnlyBuilders.contains(b) && !_denyListedBuilders.contains(b),
  );
}

const _ciOnlyBuilders = {
  'vm-aot-linux-release-arm64',
  'vm-linux-release-arm64',
};

const _denyListedBuilders = <String>{};

Stream<Map<String, dynamic>> _configurationDocuments() async* {
  String? nextPageToken;
  do {
    final requestUrl = Uri(
      scheme: 'https',
      host: 'firestore.googleapis.com',
      path: 'v1/projects/dart-ci/databases/(default)/documents/configurations',
      queryParameters: {
        'pageSize': '300',
        if (nextPageToken != null) 'pageToken': nextPageToken,
      },
    );
    final response = await _get(requestUrl);
    final object = jsonDecode(response) as Map<String, dynamic>;
    yield* Stream.fromIterable(
      (object['documents'] as List).cast<Map<String, dynamic>>(),
    );

    nextPageToken = object['nextPageToken'];
  } while (nextPageToken != null);
}

Future<Map<String, String>> _configurationBuilders() async {
  return {
    await for (final document in _configurationDocuments())
      if (document
          case {
            'name': String fullName,
            'fields': {'builder': {'stringValue': String builder}},
          })
        fullName.split('/').last: builder,
  };
}

void printHelp() {
  print(r'''
A script to find all try jobs for a set of tests.

  Usage: tools/find_builders.dart [selector] [selector2] [...]

Sample output: Cq-Include-Trybots: dart/try:vm-kernel-linux-debug-x64,...
''');
}
