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

// ignore_for_file: avoid_dynamic_calls

import 'dart:convert';

import 'package:gcloud/storage.dart';
import 'package:googleapis/storage/v1.dart' show DetailedApiRequestError;
import 'package:googleapis_auth/auth_io.dart';

import 'common.dart';
import 'constants.dart';
import 'gcs_lock.dart';

/// A [MetricPoint] modeled after the format that Skia Perf expects.
///
/// Skia Perf Format is a JSON file that looks like:
/// ```json
/// {
///     "gitHash": "fe4a4029a080bc955e9588d05a6cd9eb490845d4",
///     "key": {
///         "arch": "x86",
///         "gpu": "GTX660",
///         "model": "ShuttleA",
///         "os": "Ubuntu12"
///     },
///     "results": {
///         "ChunkAlloc_PushPop_640_480": {
///             "nonrendering": {
///                 "min_ms": 0.01485466666666667,
///                 "options": {
///                     "source_type": "bench"
///                 }
///             }
///         },
///         "DeferredSurfaceCopy_discardable_640_480": {
///             "565": {
///                 "min_ms": 2.215988,
///                 "options": {
///                     "source_type": "bench"
///                 }
///             }
///         }
///      }
///   }
/// }
/// ```
class SkiaPerfPoint extends MetricPoint {
  SkiaPerfPoint._(this.githubRepo, this.gitHash, this.testName, this.subResult,
      double? value, this._options, this.jsonUrl)
      : assert(_options[kGithubRepoKey] == null),
        assert(_options[kGitRevisionKey] == null),
        assert(_options[kNameKey] == null),
        super(
          value,
          <String, String?>{}
            ..addAll(_options)
            ..addAll(<String, String?>{
              kGithubRepoKey: githubRepo,
              kGitRevisionKey: gitHash,
              kNameKey: testName,
              kSubResultKey: subResult,
            }),
        ) {
    assert(tags[kGithubRepoKey] != null);
    assert(tags[kGitRevisionKey] != null);
    assert(tags[kNameKey] != null);
  }

  /// Construct [SkiaPerfPoint] from a well-formed [MetricPoint].
  ///
  /// The [MetricPoint] must have [kGithubRepoKey], [kGitRevisionKey],
  /// [kNameKey] in its tags for this to be successful.
  ///
  /// If the [MetricPoint] has a tag 'date', that tag will be removed so Skia
  /// perf can plot multiple metrics with different date as a single trace.
  /// Skia perf will use the git revision's date instead of this date tag in
  /// the time axis.
  factory SkiaPerfPoint.fromPoint(MetricPoint p) {
    final String? githubRepo = p.tags[kGithubRepoKey];
    final String? gitHash = p.tags[kGitRevisionKey];
    final String? name = p.tags[kNameKey];

    if (githubRepo == null || gitHash == null || name == null) {
      throw StateError(
          '$kGithubRepoKey, $kGitRevisionKey, $kNameKey must be set in'
          ' the tags of $p.');
    }

    final String subResult = p.tags[kSubResultKey] ?? kSkiaPerfValueKey;

    final Map<String, String> options = <String, String>{}..addEntries(
        p.tags.entries.where(
          (MapEntry<String, dynamic> entry) =>
              entry.key != kGithubRepoKey &&
              entry.key != kGitRevisionKey &&
              entry.key != kNameKey &&
              entry.key != kSubResultKey &&
              // https://github.com/google/benchmark automatically generates a
              // 'date' field. If it's included in options, the Skia perf won't
              // be able to connect different points in a single trace because
              // the date is always different.
              entry.key != 'date',
        ),
      );

    return SkiaPerfPoint._(
        githubRepo, gitHash, name, subResult, p.value, options, null);
  }

  /// In the format of '<owner>/<name>' such as 'flutter/flutter' or
  /// 'flutter/engine'.
  final String githubRepo;

  /// SHA such as 'ad20d368ffa09559754e4b2b5c12951341ca3b2d'
  final String? gitHash;

  /// For Flutter devicelab, this is the task name (e.g.,
  /// 'flutter_gallery__transition_perf'); for Google benchmark, this is the
  /// benchmark name (e.g., 'BM_ShellShutdown').
  ///
  /// In Skia perf web dashboard, this value can be queried and filtered by
  /// "test".
  final String testName;

  /// The name of "subResult" comes from the special treatment of "sub_result"
  /// in SkiaPerf. If not provided, its value will be set to kSkiaPerfValueKey.
  ///
  /// When Google benchmarks are converted to SkiaPerfPoint, this subResult
  /// could be "cpu_time" or "real_time".
  ///
  /// When devicelab benchmarks are converted to SkiaPerfPoint, this subResult
  /// is often the metric name such as "average_frame_build_time_millis" whereas
  /// the [testName] is the benchmark or task name such as
  /// "flutter_gallery__transition_perf".
  final String subResult;

  /// The url to the Skia perf json file in the Google Cloud Storage bucket.
  ///
  /// This can be null if the point has been stored in the bucket yet.
  final String? jsonUrl;

  Map<String, dynamic> _toSubResultJson() {
    return <String, dynamic>{
      subResult: value,
      kSkiaPerfOptionsKey: _options,
    };
  }

  /// Convert a list of SkiaPoints with the same git repo and git revision into
  /// a single json file in the Skia perf format.
  ///
  /// The list must be non-empty.
  static Map<String, dynamic> toSkiaPerfJson(List<SkiaPerfPoint> points) {
    assert(points.isNotEmpty);
    assert(() {
      for (final SkiaPerfPoint p in points) {
        if (p.githubRepo != points[0].githubRepo ||
            p.gitHash != points[0].gitHash) {
          return false;
        }
      }
      return true;
    }(), 'All points must have same githubRepo and gitHash');

    final Map<String, dynamic> results = <String, dynamic>{};
    for (final SkiaPerfPoint p in points) {
      final Map<String, dynamic> subResultJson = p._toSubResultJson();
      if (results[p.testName] == null) {
        results[p.testName] = <String, dynamic>{
          kSkiaPerfDefaultConfig: subResultJson,
        };
      } else {
        // Flutter currently doesn't support having the same name but different
        // options/configurations. If this actually happens in the future, we
        // probably can use different values of config (currently there's only
        // one kSkiaPerfDefaultConfig) to resolve the conflict.
        assert(results[p.testName][kSkiaPerfDefaultConfig][kSkiaPerfOptionsKey]
                .toString() ==
            subResultJson[kSkiaPerfOptionsKey].toString());
        assert(
            results[p.testName][kSkiaPerfDefaultConfig][p.subResult] == null);
        results[p.testName][kSkiaPerfDefaultConfig][p.subResult] = p.value;
      }
    }

    return <String, dynamic>{
      kSkiaPerfGitHashKey: points[0].gitHash,
      kSkiaPerfResultsKey: results,
    };
  }

  // Equivalent to tags without git repo, git hash, and name because those two
  // are already stored somewhere else.
  final Map<String, String> _options;
}

/// Handle writing and updates of Skia perf GCS buckets.
class SkiaPerfGcsAdaptor {
  /// Construct the adaptor given the associated GCS bucket where the data is
  /// read from and written to.
  SkiaPerfGcsAdaptor(this._gcsBucket) : assert(_gcsBucket != null);

  /// Used by Skia to differentiate json file format versions.
  static const int version = 1;

  /// Write a list of SkiaPerfPoint into a GCS file with name `objectName` in
  /// the proper json format that's understandable by Skia perf services.
  ///
  /// The `objectName` must be a properly formatted string returned by
  /// [computeObjectName].
  ///
  /// The read may retry multiple times if transient network errors with code
  /// 504 happens.
  Future<void> writePoints(
      String objectName, List<SkiaPerfPoint> points) async {
    final String jsonString = jsonEncode(SkiaPerfPoint.toSkiaPerfJson(points));
    final List<int> content = utf8.encode(jsonString);

    // Retry multiple times as GCS may return 504 timeout.
    for (int retry = 0; retry < 5; retry += 1) {
      try {
        await _gcsBucket.writeBytes(objectName, content);
        return;
      } catch (e) {
        if (e is DetailedApiRequestError && e.status == 504) {
          continue;
        }
        rethrow;
      }
    }
    // Retry one last time and let the exception go through.
    await _gcsBucket.writeBytes(objectName, content);
  }

  /// Read a list of `SkiaPerfPoint` that have been previously written to the
  /// GCS file with name `objectName`.
  ///
  /// The Github repo and revision of those points will be inferred from the
  /// `objectName`.
  ///
  /// Return an empty list if the object does not exist in the GCS bucket.
  ///
  /// The read may retry multiple times if transient network errors with code
  /// 504 happens.
  Future<List<SkiaPerfPoint>> readPoints(String objectName) async {
    // Retry multiple times as GCS may return 504 timeout.
    for (int retry = 0; retry < 5; retry += 1) {
      try {
        return await _readPointsWithoutRetry(objectName);
      } catch (e) {
        if (e is DetailedApiRequestError && e.status == 504) {
          continue;
        }
        rethrow;
      }
    }
    // Retry one last time and let the exception go through.
    return _readPointsWithoutRetry(objectName);
  }

  Future<List<SkiaPerfPoint>> _readPointsWithoutRetry(String objectName) async {
    ObjectInfo? info;

    try {
      info = await _gcsBucket.info(objectName);
    } catch (e) {
      if (e.toString().contains('No such object')) {
        return <SkiaPerfPoint>[];
      } else {
        rethrow;
      }
    }

    final Stream<List<int>> stream = _gcsBucket.read(objectName);
    final Stream<int> byteStream = stream.expand((List<int> x) => x);
    final Map<String, dynamic> decodedJson =
        jsonDecode(utf8.decode(await byteStream.toList()))
            as Map<String, dynamic>;

    final List<SkiaPerfPoint> points = <SkiaPerfPoint>[];

    final String firstGcsNameComponent = objectName.split('/')[0];
    _populateGcsNameToGithubRepoMapIfNeeded();
    final String githubRepo = _gcsNameToGithubRepo[firstGcsNameComponent]!;
    assert(githubRepo != null);

    final String? gitHash = decodedJson[kSkiaPerfGitHashKey] as String?;
    final Map<String, dynamic> results =
        decodedJson[kSkiaPerfResultsKey] as Map<String, dynamic>;
    for (final String name in results.keys) {
      final Map<String, dynamic> subResultMap =
          results[name][kSkiaPerfDefaultConfig] as Map<String, dynamic>;
      for (final String subResult
          in subResultMap.keys.where((String s) => s != kSkiaPerfOptionsKey)) {
        points.add(SkiaPerfPoint._(
          githubRepo,
          gitHash,
          name,
          subResult,
          subResultMap[subResult] as double?,
          (subResultMap[kSkiaPerfOptionsKey] as Map<String, dynamic>)
              .cast<String, String>(),
          info.downloadLink.toString(),
        ));
      }
    }
    return points;
  }

  /// Compute the GCS file name that's used to store metrics for a given commit
  /// (git revision).
  ///
  /// Skia perf needs all directory names to be well formatted. The final name
  /// of the json file can be arbitrary, and multiple json files can be put
  /// in that leaf directory. We are using multiple json files divided by test
  /// names to scale up the system to avoid too many writes competing for
  /// the same json file.
  static Future<String> computeObjectName(String githubRepo, String? revision,
      DateTime commitTime, String taskName) async {
    assert(_githubRepoToGcsName[githubRepo] != null);
    final String? topComponent = _githubRepoToGcsName[githubRepo];
    // [commitTime] is not guranteed to be UTC. Ensure it is so all results
    // pushed to GCS are the same timezone.
    final DateTime commitUtcTime = commitTime.toUtc();
    final String month = commitUtcTime.month.toString().padLeft(2, '0');
    final String day = commitUtcTime.day.toString().padLeft(2, '0');
    final String hour = commitUtcTime.hour.toString().padLeft(2, '0');
    final String dateComponents = '${commitUtcTime.year}/$month/$day/$hour';
    return '$topComponent/$dateComponents/$revision/${taskName}_values.json';
  }

  static final Map<String, String> _githubRepoToGcsName = <String, String>{
    kFlutterFrameworkRepo: 'flutter-flutter',
    kFlutterEngineRepo: 'flutter-engine',
  };
  static final Map<String?, String> _gcsNameToGithubRepo = <String?, String>{};

  static void _populateGcsNameToGithubRepoMapIfNeeded() {
    if (_gcsNameToGithubRepo.isEmpty) {
      for (final String repo in _githubRepoToGcsName.keys) {
        final String? gcsName = _githubRepoToGcsName[repo];
        assert(_gcsNameToGithubRepo[gcsName] == null);
        _gcsNameToGithubRepo[gcsName] = repo;
      }
    }
  }

  final Bucket _gcsBucket;
}

/// A [MetricDestination] that conforms to Skia Perf's protocols.
class SkiaPerfDestination extends MetricDestination {
  /// Creates a new [SkiaPerfDestination].
  SkiaPerfDestination(this._gcs, this._lock);

  /// Create from a full credentials json (of a service account).
  static Future<SkiaPerfDestination> makeFromGcpCredentials(
      Map<String, dynamic> credentialsJson,
      {bool isTesting = false}) async {
    final AutoRefreshingAuthClient client = await clientViaServiceAccount(
        ServiceAccountCredentials.fromJson(credentialsJson), Storage.SCOPES);
    return make(
      client,
      credentialsJson[kProjectId] as String,
      isTesting: isTesting,
    );
  }

  /// Create from an access token and its project id.
  static Future<SkiaPerfDestination> makeFromAccessToken(
      String token, String projectId,
      {bool isTesting = false}) async {
    final AuthClient client = authClientFromAccessToken(token, Storage.SCOPES);
    return make(client, projectId, isTesting: isTesting);
  }

  /// Create from an [AuthClient] and a GCP project id.
  ///
  /// [AuthClient] can be obtained from functions like `clientViaUserConsent`.
  static Future<SkiaPerfDestination> make(AuthClient client, String projectId,
      {bool isTesting = false}) async {
    final Storage storage = Storage(client, projectId);
    final String bucketName = isTesting ? kTestBucketName : kBucketName;
    if (!await storage.bucketExists(bucketName)) {
      throw StateError('Bucket $bucketName does not exist.');
    }
    final SkiaPerfGcsAdaptor adaptor =
        SkiaPerfGcsAdaptor(storage.bucket(bucketName));
    final GcsLock lock = GcsLock(client, bucketName);
    return SkiaPerfDestination(adaptor, lock);
  }

  @override
  Future<void> update(
      List<MetricPoint> points, DateTime commitTime, String taskName) async {
    // 1st, create a map based on git repo, git revision, and point id. Git repo
    // and git revision are the top level components of the Skia perf GCS object
    // name.
    final Map<String, Map<String?, Map<String, SkiaPerfPoint>>> pointMap =
        <String, Map<String, Map<String, SkiaPerfPoint>>>{};
    for (final SkiaPerfPoint p
        in points.map((MetricPoint x) => SkiaPerfPoint.fromPoint(x))) {
      if (p != null) {
        pointMap[p.githubRepo] ??= <String, Map<String, SkiaPerfPoint>>{};
        pointMap[p.githubRepo]![p.gitHash] ??= <String, SkiaPerfPoint>{};
        pointMap[p.githubRepo]![p.gitHash]![p.id] = p;
      }
    }

    // All created locks must be released before returning
    final List<Future<void>> lockFutures = <Future<void>>[];

    // 2nd, read existing points from the gcs object and update with new ones.
    for (final String repo in pointMap.keys) {
      for (final String? revision in pointMap[repo]!.keys) {
        final String objectName = await SkiaPerfGcsAdaptor.computeObjectName(
            repo, revision, commitTime, taskName);
        final Map<String, SkiaPerfPoint>? newPoints = pointMap[repo]![revision];
        // Too many bots writing the metrics of a git revision into a single json
        // file will cause high contention on the lock. We use multiple
        // json files according to task names. Skia perf read all json files in
        // the directory so one can use arbitrary names for those sharded json
        // file names.
        lockFutures.add(
          _lock!.protectedRun('$objectName.lock', () async {
            final List<SkiaPerfPoint> oldPoints =
                await _gcs.readPoints(objectName);
            for (final SkiaPerfPoint p in oldPoints) {
              if (newPoints![p.id] == null) {
                newPoints[p.id] = p;
              }
            }
            await _gcs.writePoints(objectName, newPoints!.values.toList());
          }),
        );
      }
    }
    await Future.wait(lockFutures);
  }

  final SkiaPerfGcsAdaptor _gcs;
  late final GcsLock? _lock;
}
