#!/usr/bin/env dart
// 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.

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

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

final parser = ArgParser()
  ..addMultiOption('bot',
      abbr: 'b',
      help: 'Select the bots matching the glob pattern [option is repeatable]',
      splitCommas: false)
  ..addFlag('verbose', abbr: 'v', help: 'Verbose output.', negatable: false)
  ..addFlag('help', help: 'Show the program usage.', negatable: false);

void printUsage() {
  print("""
Usage: ${Platform.executable} ${Platform.script} [OLDER_COMMIT] [NEWER_COMMIT]

The options are as follows:

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

late bool verbose;

main(List<String> args) async {
  final options = parser.parse(args);
  if (options["help"]) {
    printUsage();
    return;
  }

  final commits = options.rest;
  if (commits.length < 2) {
    print('Need to supply at least two commits.');
    printUsage();
    exitCode = 1;
    return;
  }
  verbose = options['verbose'] ?? false;

  final globs = List<Glob>.from(options["bot"].map((pattern) => Glob(pattern)));
  final vmBuilders = loadVmBuildersFromTestMatrix(globs);

  final futures = <Future<List<Result>>>[];
  for (final commit in commits) {
    final DateTime date = await getDateOfCommit(commit);
    futures.add(getResults(commit, date, vmBuilders));
  }

  final results = await Future.wait(futures);
  for (int i = 0; i < results.length - 1; i++) {
    final commitB = commits[i];
    final commitA = commits[i + 1];

    print('\nResult changes between $commitB -> $commitA:');
    final commonGroups =
        buildCommonGroups(commitA, commitB, results[i], results[i + 1]);
    for (final commonGroup in commonGroups) {
      final builders = commonGroup.builders;

      print('');
      for (final group in commonGroup.groups) {
        final diff = group.diffs.first;
        print('${group.test} ${diff.before} -> ${diff.after}');
      }
      for (final b in extractBuilderPattern(builders)) {
        print('   on $b');
      }
    }
  }
}

Future<DateTime> getDateOfCommit(String commit) async {
  final result = await Process.run(
      'git', ['show', '-s', '--format=%cd', '--date=iso-strict', commit]);
  if (result.exitCode != 0) {
    print('Could not determine date of commit $commit. Git reported:\n');
    print(result.stdout);
    print(result.stderr);
    exit(1);
  }
  return DateTime.parse(result.stdout.trim());
}

Future<List<Result>> getResults(
    String commit, DateTime dateC, Set<String> builders) async {
  final DateTime date0 = dateC.add(const Duration(hours: 24));
  final DateTime date2 = dateC.subtract(const Duration(hours: 24));
  final query = '''
      SELECT commit_time, builder_name, build_number, name, result, expected FROM `dart-ci.results.results`
      WHERE commit_hash="$commit"
        AND matches=false
        AND (_PARTITIONDATE = "${formatDate(date0)}" OR
             _PARTITIONDATE = "${formatDate(dateC)}" OR
             _PARTITIONDATE = "${formatDate(date2)}" )
        AND (STARTS_WITH(builder_name, "vm-") OR
             STARTS_WITH(builder_name, "app-") OR
             STARTS_WITH(builder_name, "cross-"))
        AND ((flaky is NULL) OR flaky=false)
        ORDER BY name''';

  final arguments = <String>[
    'query',
    '--format=prettyjson',
    '--project_id=dart-ci',
    '--nouse_legacy_sql',
    '-n',
    '1000000',
    query,
  ];
  if (verbose) {
    print('Executing query:\n    bq ${arguments.join(' ')}');
  }

  final result = await Process.run('bq', arguments);
  if (result.exitCode == 0) {
    File('$commit.json').writeAsStringSync(result.stdout);
    final resultsForCommit = json.decode(result.stdout);

    final results = <Result>[];
    for (final Map<String, dynamic> result in resultsForCommit) {
      final builderName = result['builder_name'];
      if (!builders.contains(builderName)) {
        continue;
      }

      final failure = Result(commit, builderName, result['build_number'],
          result['name'], result['expected'], result['result']);
      results.add(failure);
    }

    results.sort((Result a, Result b) {
      final c = a.name.compareTo(b.name);
      if (c != 0) return c;
      return a.builderName.compareTo(b.builderName);
    });

    return results;
  } else {
    print('Running the following query failed:\nbq ${arguments.join(' ')}');
    print('Exit code: ${result.exitCode}');
    final stdout = result.stdout.trim();
    if (stdout.length > 0) {
      print('Stdout:\n$stdout');
    }
    final stderr = result.stderr.trim();
    if (stderr.length > 0) {
      print('Stderr:\n$stderr');
    }
    return <Result>[];
  }
}

List<CommonGroup> buildCommonGroups(String commitA, String commitB,
    List<Result> commitResults, List<Result> commitResultsBefore) {
  // If a test has same outcome across many vm builders
  final diffs = <Diff>[];
  int i = 0;
  int j = 0;
  while (i < commitResultsBefore.length && j < commitResults.length) {
    final a = commitResultsBefore[i];
    final b = commitResults[j];

    // Is a smaller than b, then we had a failure before and no longer one.
    if (a.name.compareTo(b.name) < 0 ||
        (a.name.compareTo(b.name) == 0 &&
            a.builderName.compareTo(b.builderName) < 0)) {
      diffs.add(Diff(a, null));
      i++;
      continue;
    }

    // Is b smaller than a, then we had no failure before but have one now.
    if (b.name.compareTo(a.name) < 0 ||
        (b.name.compareTo(a.name) == 0 &&
            b.builderName.compareTo(a.builderName) < 0)) {
      diffs.add(Diff(null, b));
      j++;
      continue;
    }

    // Else we must have the same name and builder.
    if (a.name != b.name || a.builderName != b.builderName) throw 'BUG';

    if (a.expected != b.expected || a.result != b.result) {
      diffs.add(Diff(a, b));
    }
    i++;
    j++;
  }

  while (i < commitResultsBefore.length) {
    final a = commitResultsBefore[i++];
    diffs.add(Diff(a, null));
  }

  while (j < commitResults.length) {
    final b = commitResults[j++];
    diffs.add(Diff(null, b));
  }

  // If a test has same outcome across many vm builders
  final groups = <GroupedDiff>[];
  int h = 0;
  while (h < diffs.length) {
    final d = diffs[h++];
    final builders = <String>{}..add(d.builder);
    final gropupDiffs = <Diff>[d];

    while (h < diffs.length) {
      final nd = diffs[h];
      if (d.test == nd.test) {
        if (d.sameExpectationDifferenceAs(nd)) {
          builders.add(nd.builder);
          gropupDiffs.add(nd);
          h++;
          continue;
        }
      }
      break;
    }

    groups.add(GroupedDiff(d.test, builders.toList()..sort(), gropupDiffs));
  }

  final commonGroups = <String, List<GroupedDiff>>{};
  for (final group in groups) {
    final key = group.builders.join(' ');
    commonGroups.putIfAbsent(key, () => <GroupedDiff>[]).add(group);
  }

  final commonGroupList = commonGroups.values
      .map((list) => CommonGroup(list.first.builders, list))
      .toList();
  commonGroupList
      .sort((a, b) => a.builders.length.compareTo(b.builders.length));
  return commonGroupList;
}

class CommonGroup {
  final List<String> builders;
  final List<GroupedDiff> groups;
  CommonGroup(this.builders, this.groups);
}

class GroupedDiff {
  final String test;
  final List<String> builders;
  final List<Diff> diffs;

  GroupedDiff(this.test, this.builders, this.diffs);
}

class Diff {
  final Result? before;
  final Result? after;

  Diff(this.before, this.after);

  String get test => (before?.name ?? after?.name)!;
  String get builder => (before?.builderName ?? after?.builderName)!;

  bool sameExpectationDifferenceAs(Diff other) {
    if ((before == null) != (other.before == null)) return false;
    if ((after == null) != (other.after == null)) return false;

    if (before != null) {
      if (!before!.sameResult(other.before!)) return false;
    }
    if (after != null) {
      if (!after!.sameResult(other.after!)) return false;
    }
    return true;
  }
}

class Result {
  final String commit;
  final String builderName;
  final String buildNumber;
  final String name;
  final String expected;
  final String result;

  Result(this.commit, this.builderName, this.buildNumber, this.name,
      this.expected, this.result);

  @override
  String toString() => '(expected: $expected, actual: $result)';

  bool sameResult(Result other) {
    return name == other.name &&
        expected == other.expected &&
        result == other.result;
  }

  bool equals(other) {
    if (other is Result) {
      if (name != other.name) return false;
      if (builderName != other.builderName) return false;
    }
    return false;
  }

  @override
  int get hashCode => name.hashCode ^ builderName.hashCode;

  @override
  // ignore: unnecessary_overrides
  bool operator ==(Object other) {
    // TODO: implement ==
    return super == other;
  }
}

String currentDate() {
  final timestamp = DateTime.now().toUtc().toIso8601String();
  return timestamp.substring(0, timestamp.indexOf('T'));
}

Set<String> loadVmBuildersFromTestMatrix(List<Glob> globs) {
  final contents = File('tools/bots/test_matrix.json').readAsStringSync();
  final testMatrix = json.decode(contents);

  final vmBuilders = <String>{};
  for (final config in testMatrix['builder_configurations']) {
    for (final builder in config['builders']) {
      if (builder.startsWith('vm-') || builder.startsWith('app-')) {
        vmBuilders.add(builder);
      }
    }
  }

  // This one is in the test_matrix.json but we don't run it on CI.
  vmBuilders.remove('vm-kernel-asan-linux-release-ia32');

  if (globs.isNotEmpty) {
    vmBuilders.removeWhere((String builder) {
      return !globs.any((Glob glob) => glob.matches(builder));
    });
  }

  return vmBuilders;
}

List<String> extractBuilderPattern(List<String> builders) {
  final all = Set<String>.from(builders);

  String reduce(String builder, List<String> posibilities) {
    for (final pos in posibilities) {
      if (builder.contains(pos)) {
        final existing = <String>[];
        final available = <String>[];
        for (final pos2 in posibilities) {
          final builder2 = builder.replaceFirst(pos, pos2);
          if (all.contains(builder2)) {
            existing.add(builder2);
            available.add(pos2);
          }
        }
        if (existing.length > 1) {
          all.removeAll(existing);
          final replacement =
              builder.replaceFirst(pos, '{${available.join(',')}}');
          all.add(replacement);
          return replacement;
        }
      }
    }
    return builder;
  }

  for (String builder in builders) {
    if (all.contains(builder)) {
      builder = reduce(builder, const ['debug', 'release', 'product']);
    }
  }
  for (String builder in all.toList()) {
    if (all.contains(builder)) {
      builder = reduce(builder, const ['mac', 'linux', 'win']);
    }
  }

  for (String builder in all.toList()) {
    if (all.contains(builder)) {
      builder = reduce(builder, const [
        'ia32',
        'x64',
        'simarm',
        'simarm64',
        'arm',
        'arm64',
      ]);
    }
  }
  return all.toList()..sort();
}

String formatDate(DateTime date) {
  final s = date.toIso8601String();
  return s.substring(0, s.indexOf('T'));
}
