// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.6

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

import 'package:args/args.dart';
import 'package:metrics_center/metrics_center.dart';
import 'package:path/path.dart' as p;

Future<ProcessResult> runGit(
  List<String> args, {
  String processWorkingDir,
}) async {
  return Process.run(
    'git',
    args,
    workingDirectory: processWorkingDir,
    runInShell: true,
  );
}

Future<List<String>> getGitLog() async {
  final String gitRoot = p.absolute('../..');
  // Somehow gitDir.currentBranch() doesn't work in Cirrus with "fatal: 'HEAD' -
  // not a valid ref". Therefore, we use "git log" to get the revision manually.
  final ProcessResult logResult = await runGit(
    <String>['log', '--pretty=format:%H %ct', '-n', '1'],
    processWorkingDir: gitRoot,
  );
  if (logResult.exitCode != 0) {
    throw 'Unexpected exit code ${logResult.exitCode}';
  }
  return logResult.stdout.toString().trim().split(' ');
}

class PointsAndDate {
  PointsAndDate(this.points, this.date);

  final List<FlutterEngineMetricPoint> points;
  final String date;
}

Future<PointsAndDate> parse(String jsonFileName) async {
  final List<String> gitLog = await getGitLog();
  final String gitRevision = gitLog[0];
  final String gitCommitDate = gitLog[1];
  final List<MetricPoint> rawPoints = await GoogleBenchmarkParser.parse(
    jsonFileName,
  );
  final List<FlutterEngineMetricPoint> points = <FlutterEngineMetricPoint>[];
  for (final MetricPoint rawPoint in rawPoints) {
    points.add(FlutterEngineMetricPoint(
      rawPoint.tags[kNameKey],
      rawPoint.value,
      gitRevision,
      moreTags: rawPoint.tags,
    ));
  }
  return PointsAndDate(points, gitCommitDate);
}

Future<FlutterDestination> connectFlutterDestination() async {
  const String kTokenPath = 'TOKEN_PATH';
  const String kGcpProject = 'GCP_PROJECT';
  final Map<String, String> env = Platform.environment;
  final bool isTesting = env['IS_TESTING'] == 'true';
  if (env.containsKey(kTokenPath) && env.containsKey(kGcpProject)) {
    return FlutterDestination.makeFromAccessToken(
      File(env[kTokenPath]).readAsStringSync(),
      env[kGcpProject],
      isTesting: isTesting,
    );
  }
  return FlutterDestination.makeFromCredentialsJson(
    jsonDecode(Platform.environment['BENCHMARK_GCP_CREDENTIALS'])
        as Map<String, dynamic>,
    isTesting: isTesting,
  );
}

ArgParser _serupOptions() {
  final ArgParser parser = ArgParser();
  parser.addOption(
    'json',
    mandatory: true,
    help: 'Path to the benchmarks json file.',
  );
  parser.addFlag(
    'no-upload',
    help: 'Upload the parsed benchmarks.',
    defaultsTo: false,
  );
  return parser;
}

Future<void> main(List<String> args) async {
  final ArgParser parser = _serupOptions();
  final ArgResults options = parser.parse(args);

  final String json = options['json'] as String;
  final PointsAndDate pointsAndDate = await parse(json);

  final bool noUpload = options['no-upload'] as bool;
  if (noUpload) {
    return;
  }

  // The data will be sent to the Datastore of the GCP project specified through
  // environment variable BENCHMARK_GCP_CREDENTIALS, or TOKEN_PATH/GCP_PROJECT.
  // The engine Cirrus job has currently configured the GCP project to
  // flutter-cirrus for test. We'll eventually migrate to flutter-infra project
  // once the test is done.
  final FlutterDestination destination = await connectFlutterDestination();
  await destination.update(
    pointsAndDate.points,
    DateTime.fromMillisecondsSinceEpoch(
      int.parse(pointsAndDate.date) * 1000,
      isUtc: true,
    ),
    'flutter_engine_benchmark',
  );
}
