// Copyright 2014 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.

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

import 'package:collection/collection.dart';
import 'package:metrics_center/metrics_center.dart';

/// Authenticate and connect to gcloud storage.
///
/// It supports both token and credential authentications.
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(env['BENCHMARK_GCP_CREDENTIALS']!) as Map<String, dynamic>,
    isTesting: isTesting,
  );
}

/// Parse results and append additional benchmark tags into Metric Points.
///
/// An example of `resultsJson`:
///   {
///     "CommitBranch": "master",
///     "CommitSha": "abc",
///     "BuilderName": "test",
///     "ResultData": {
///       "average_frame_build_time_millis": 0.4550425531914895,
///       "90th_percentile_frame_build_time_millis": 0.473
///     },
///     "BenchmarkScoreKeys": [
///       "average_frame_build_time_millis",
///       "90th_percentile_frame_build_time_millis"
///     ]
///   }
///
/// An example of `benchmarkTags`:
///   {
///     "arch": "intel",
///     "device_type": "Moto G Play",
///     "device_version": "android-25",
///     "host_type": "linux",
///     "host_version": "debian-10.11"
///   }
List<MetricPoint> parse(Map<String, dynamic> resultsJson, Map<String, dynamic> benchmarkTags, String taskName) {
  print('Results to upload to skia perf: $resultsJson');
  print('Benchmark tags to upload to skia perf: $benchmarkTags');
  final List<String> scoreKeys =
      (resultsJson['BenchmarkScoreKeys'] as List<dynamic>?)?.cast<String>() ?? const <String>[];
  final Map<String, dynamic> resultData =
      resultsJson['ResultData'] as Map<String, dynamic>? ?? const <String, dynamic>{};
  final String gitBranch = (resultsJson['CommitBranch'] as String).trim();
  final String gitSha = (resultsJson['CommitSha'] as String).trim();
  final List<MetricPoint> metricPoints = <MetricPoint>[];
  for (final String scoreKey in scoreKeys) {
    Map<String, String> tags = <String, String>{
      kGithubRepoKey: kFlutterFrameworkRepo,
      kGitRevisionKey: gitSha,
      'branch': gitBranch,
      kNameKey: taskName,
      kSubResultKey: scoreKey,
    };
    // Append additional benchmark tags, which will surface in Skia Perf dashboards.
    tags = mergeMaps<String, String>(
        tags, benchmarkTags.map((String key, dynamic value) => MapEntry<String, String>(key, value.toString())));
    metricPoints.add(
      MetricPoint(
        (resultData[scoreKey] as num).toDouble(),
        tags,
      ),
    );
  }
  return metricPoints;
}

/// Upload metrics to GCS bucket used by Skia Perf.
///
/// Skia Perf picks up all available files under the folder, and
/// is robust to duplicate entries.
///
/// Files will be named based on `taskName`, such as
/// `complex_layout_scroll_perf__timeline_summary_values.json`.
/// If no `taskName` is specified, data will be saved to
/// `default_values.json`.
Future<void> upload(
  FlutterDestination metricsDestination,
  List<MetricPoint> metricPoints,
  int commitTimeSinceEpoch,
  String taskName,
) async {
  await metricsDestination.update(
    metricPoints,
    DateTime.fromMillisecondsSinceEpoch(
      commitTimeSinceEpoch,
      isUtc: true,
    ),
    taskName,
  );
}

/// Upload JSON results to skia perf.
///
/// Flutter infrastructure's workflow is:
/// 1. Run DeviceLab test, writing results to a known path
/// 2. Request service account token from luci auth (valid for at least 3 minutes)
/// 3. Upload results from (1) to skia perf.
Future<void> uploadToSkiaPerf(String? resultsPath, String? commitTime, String? taskName, String? benchmarkTags) async {
  int commitTimeSinceEpoch;
  if (resultsPath == null) {
    return;
  }
  if (commitTime != null) {
    commitTimeSinceEpoch = 1000 * int.parse(commitTime);
  } else {
    commitTimeSinceEpoch = DateTime.now().millisecondsSinceEpoch;
  }
  taskName = taskName ?? 'default';
  final Map<String, dynamic> benchmarkTagsMap = jsonDecode(benchmarkTags ?? '{}') as Map<String, dynamic>;
  final File resultFile = File(resultsPath);
  Map<String, dynamic> resultsJson = <String, dynamic>{};
  resultsJson = json.decode(await resultFile.readAsString()) as Map<String, dynamic>;
  final List<MetricPoint> metricPoints = parse(resultsJson, benchmarkTagsMap, taskName);
  final FlutterDestination metricsDestination = await connectFlutterDestination();
  await upload(
    metricsDestination,
    metricPoints,
    commitTimeSinceEpoch,
    metricFileName(taskName, benchmarkTagsMap),
  );
}

/// Create metric file name based on `taskName`, `arch`, `host type`, and `device type`.
///
/// Same `taskName` may run on different platforms. Considering host/device tags to
/// use different metric file names.
///
/// This affects only the metric file name which contains metric data, and does not affect
/// real host/device tags.
///
/// For example:
///   Old file name: `backdrop_filter_perf__timeline_summary`
///   New file name: `backdrop_filter_perf__timeline_summary_intel_linux_motoG4`
String metricFileName(
  String taskName,
  Map<String, dynamic> benchmarkTagsMap,
) {
  final StringBuffer fileName = StringBuffer(taskName);
  if (benchmarkTagsMap.containsKey('arch')) {
    fileName
      ..write('_')
      ..write(_fileNameFormat(benchmarkTagsMap['arch'] as String));
  }
  if (benchmarkTagsMap.containsKey('host_type')) {
    fileName
      ..write('_')
      ..write(_fileNameFormat(benchmarkTagsMap['host_type'] as String));
  }
  if (benchmarkTagsMap.containsKey('device_type')) {
    fileName
      ..write('_')
      ..write(_fileNameFormat(benchmarkTagsMap['device_type'] as String));
  }
  return fileName.toString();
}

/// Format `fileName` removing non letter and number characters.
String _fileNameFormat(String fileName) {
  return fileName.replaceAll(RegExp('[^a-zA-Z0-9]'), '');
}
