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

// @dart = 2.8

import 'dart:convert' show json, JsonEncoder;
import 'dart:math' as math;

import 'package:file/file.dart';
import 'package:path/path.dart' as path;

import 'common.dart';
import 'percentile_utils.dart';
import 'profiling_summarizer.dart';
import 'scene_display_lag_summarizer.dart';
import 'timeline.dart';

const JsonEncoder _prettyEncoder = JsonEncoder.withIndent('  ');

/// The maximum amount of time considered safe to spend for a frame's build
/// phase. Anything past that is in the danger of missing the frame as 60FPS.
const Duration kBuildBudget = Duration(milliseconds: 16);

/// The name of the framework frame build events we need to filter or extract.
const String kBuildFrameEventName = 'Frame';

/// The name of the engine frame rasterization events we need to filter or extract.
const String kRasterizeFrameEventName = 'GPURasterizer::Draw';

/// Extracts statistics from a [Timeline].
class TimelineSummary {
  /// Creates a timeline summary given a full timeline object.
  TimelineSummary.summarize(this._timeline);

  final Timeline _timeline;

  /// Average amount of time spent per frame in the framework building widgets,
  /// updating layout, painting and compositing.
  ///
  /// Returns null if no frames were recorded.
  double computeAverageFrameBuildTimeMillis() {
    return _averageInMillis(_extractFrameDurations());
  }

  /// The [p]-th percentile frame rasterization time in milliseconds.
  ///
  /// Returns null if no frames were recorded.
  double computePercentileFrameBuildTimeMillis(double p) {
    return _percentileInMillis(_extractFrameDurations(), p);
  }

  /// The longest frame build time in milliseconds.
  ///
  /// Returns null if no frames were recorded.
  double computeWorstFrameBuildTimeMillis() {
    return _maxInMillis(_extractFrameDurations());
  }

  /// The number of frames that missed the [kBuildBudget] and therefore are
  /// in the danger of missing frames.
  int computeMissedFrameBuildBudgetCount([ Duration frameBuildBudget = kBuildBudget ]) => _extractFrameDurations()
    .where((Duration duration) => duration > kBuildBudget)
    .length;

  /// Average amount of time spent per frame in the engine rasterizer.
  ///
  /// Returns null if no frames were recorded.
  double computeAverageFrameRasterizerTimeMillis() {
    return _averageInMillis(_extractGpuRasterizerDrawDurations());
  }

  /// The longest frame rasterization time in milliseconds.
  ///
  /// Returns null if no frames were recorded.
  double computeWorstFrameRasterizerTimeMillis() {
    return _maxInMillis(_extractGpuRasterizerDrawDurations());
  }

  /// The [p]-th percentile frame rasterization time in milliseconds.
  ///
  /// Returns null if no frames were recorded.
  double computePercentileFrameRasterizerTimeMillis(double p) {
    return _percentileInMillis(_extractGpuRasterizerDrawDurations(), p);
  }

  /// The number of frames that missed the [kBuildBudget] on the raster thread
  /// and therefore are in the danger of missing frames.
  int computeMissedFrameRasterizerBudgetCount([ Duration frameBuildBudget = kBuildBudget ]) => _extractGpuRasterizerDrawDurations()
      .where((Duration duration) => duration > kBuildBudget)
      .length;

  /// The total number of frames recorded in the timeline.
  int countFrames() => _extractFrameDurations().length;

  /// The total number of rasterizer cycles recorded in the timeline.
  int countRasterizations() => _extractGpuRasterizerDrawDurations().length;

  /// Encodes this summary as JSON.
  ///
  /// Data ends with "_time_millis" means time in milliseconds and numbers in
  /// the "frame_build_times", "frame_rasterizer_times", "frame_begin_times" and
  /// "frame_rasterizer_begin_times" lists are in microseconds.
  ///
  /// * "average_frame_build_time_millis": Average amount of time spent per
  ///   frame in the framework building widgets, updating layout, painting and
  ///   compositing.
  ///   See [computeAverageFrameBuildTimeMillis].
  /// * "90th_percentile_frame_build_time_millis" and
  ///   "99th_percentile_frame_build_time_millis": The p-th percentile frame
  ///   rasterization time in milliseconds. 90 and 99-th percentile number is
  ///   usually a better metric to estimate worse cases. See discussion in
  ///   https://github.com/flutter/flutter/pull/19121#issuecomment-419520765
  ///   See [computePercentileFrameBuildTimeMillis].
  /// * "worst_frame_build_time_millis": The longest frame build time.
  ///   See [computeWorstFrameBuildTimeMillis].
  /// * "missed_frame_build_budget_count': The number of frames that missed
  ///   the [kBuildBudget] and therefore are in the danger of missing frames.
  ///   See [computeMissedFrameBuildBudgetCount].
  /// * "average_frame_rasterizer_time_millis": Average amount of time spent
  ///   per frame in the engine rasterizer.
  ///   See [computeAverageFrameRasterizerTimeMillis].
  /// * "90th_percentile_frame_rasterizer_time_millis" and
  ///   "99th_percentile_frame_rasterizer_time_millis": The 90/99-th percentile
  ///   frame rasterization time in milliseconds.
  ///   See [computePercentileFrameRasterizerTimeMillis].
  /// * "worst_frame_rasterizer_time_millis": The longest frame rasterization
  ///   time.
  ///   See [computeWorstFrameRasterizerTimeMillis].
  /// * "missed_frame_rasterizer_budget_count": The number of frames that missed
  ///   the [kBuildBudget] on the raster thread and therefore are in the danger
  ///   of missing frames.
  ///   See [computeMissedFrameRasterizerBudgetCount].
  /// * "frame_count": The total number of frames recorded in the timeline. This
  ///   is also the length of the "frame_build_times" and the "frame_begin_times"
  ///   lists.
  ///   See [countFrames].
  /// * "frame_rasterizer_count": The total number of rasterizer cycles recorded
  ///   in the timeline. This is also the length of the "frame_rasterizer_times"
  ///   and the "frame_rasterizer_begin_times" lists.
  ///   See [countRasterizations].
  /// * "frame_build_times": The build time of each frame, by tracking the
  ///   [TimelineEvent] with name [kBuildFrameEventName].
  /// * "frame_rasterizer_times": The rasterize time of each frame, by tracking
  ///   the [TimelineEvent] with name [kRasterizeFrameEventName]
  /// * "frame_begin_times": The build begin timestamp of each frame.
  /// * "frame_rasterizer_begin_times": The rasterize begin time of each frame.
  /// * "average_vsync_transitions_missed": Computes the average of the
  ///   `vsync_transitions_missed` over the lag events.
  ///   See [SceneDisplayLagSummarizer.computeAverageVsyncTransitionsMissed].
  /// * "90th_percentile_vsync_transitions_missed" and
  ///   "99th_percentile_vsync_transitions_missed": The 90/99-th percentile
  ///   `vsync_transitions_missed` over the lag events.
  ///   See [SceneDisplayLagSummarizer.computePercentileVsyncTransitionsMissed].
  Map<String, dynamic> get summaryJson {
    final SceneDisplayLagSummarizer sceneDisplayLagSummarizer = _sceneDisplayLagSummarizer();
    final Map<String, dynamic> profilingSummary = _profilingSummarizer().summarize();

    final Map<String, dynamic> timelineSummary = <String, dynamic>{
      'average_frame_build_time_millis': computeAverageFrameBuildTimeMillis(),
      '90th_percentile_frame_build_time_millis': computePercentileFrameBuildTimeMillis(90.0),
      '99th_percentile_frame_build_time_millis': computePercentileFrameBuildTimeMillis(99.0),
      'worst_frame_build_time_millis': computeWorstFrameBuildTimeMillis(),
      'missed_frame_build_budget_count': computeMissedFrameBuildBudgetCount(),
      'average_frame_rasterizer_time_millis': computeAverageFrameRasterizerTimeMillis(),
      '90th_percentile_frame_rasterizer_time_millis': computePercentileFrameRasterizerTimeMillis(90.0),
      '99th_percentile_frame_rasterizer_time_millis': computePercentileFrameRasterizerTimeMillis(99.0),
      'worst_frame_rasterizer_time_millis': computeWorstFrameRasterizerTimeMillis(),
      'missed_frame_rasterizer_budget_count': computeMissedFrameRasterizerBudgetCount(),
      'frame_count': countFrames(),
      'frame_rasterizer_count': countRasterizations(),
      'frame_build_times': _extractFrameDurations()
          .map<int>((Duration duration) => duration.inMicroseconds)
          .toList(),
      'frame_rasterizer_times': _extractGpuRasterizerDrawDurations()
          .map<int>((Duration duration) => duration.inMicroseconds)
          .toList(),
      'frame_begin_times': _extractBeginTimestamps(kBuildFrameEventName)
          .map<int>((Duration duration) => duration.inMicroseconds)
          .toList(),
      'frame_rasterizer_begin_times': _extractBeginTimestamps(kRasterizeFrameEventName)
          .map<int>((Duration duration) => duration.inMicroseconds)
          .toList(),
      'average_vsync_transitions_missed': sceneDisplayLagSummarizer.computeAverageVsyncTransitionsMissed(),
      '90th_percentile_vsync_transitions_missed': sceneDisplayLagSummarizer.computePercentileVsyncTransitionsMissed(90.0),
      '99th_percentile_vsync_transitions_missed': sceneDisplayLagSummarizer.computePercentileVsyncTransitionsMissed(99.0),
    };

    timelineSummary.addAll(profilingSummary);
    return timelineSummary;
  }

  /// Writes all of the recorded timeline data to a file.
  ///
  /// See also:
  ///
  /// * [Timeline.fromJson], which explains detail about the timeline data.
  Future<void> writeTimelineToFile(
    String traceName, {
    String destinationDirectory,
    bool pretty = false,
  }) async {
    destinationDirectory ??= testOutputsDirectory;
    await fs.directory(destinationDirectory).create(recursive: true);
    final File file = fs.file(path.join(destinationDirectory, '$traceName.timeline.json'));
    await file.writeAsString(_encodeJson(_timeline.json, pretty));
  }

  /// Writes [summaryJson] to a file.
  Future<void> writeSummaryToFile(
    String traceName, {
    String destinationDirectory,
    bool pretty = false,
  }) async {
    destinationDirectory ??= testOutputsDirectory;
    await fs.directory(destinationDirectory).create(recursive: true);
    final File file = fs.file(path.join(destinationDirectory, '$traceName.timeline_summary.json'));
    await file.writeAsString(_encodeJson(summaryJson, pretty));
  }

  String _encodeJson(Map<String, dynamic> jsonObject, bool pretty) {
    return pretty
      ? _prettyEncoder.convert(jsonObject)
      : json.encode(jsonObject);
  }

  List<TimelineEvent> _extractNamedEvents(String name) {
    return _timeline.events
      .where((TimelineEvent event) => event.name == name)
      .toList();
  }

  List<TimelineEvent> _extractEventsWithNames(Set<String> names) {
    return _timeline.events
      .where((TimelineEvent event) => names.contains(event.name))
      .toList();
  }

  List<Duration> _extractDurations(
    String name,
    Duration extractor(TimelineEvent beginEvent, TimelineEvent endEvent),
  ) {
    final List<Duration> result = <Duration>[];
    final List<TimelineEvent> events = _extractNamedEvents(name);

    // Timeline does not guarantee that the first event is the "begin" event.
    TimelineEvent begin;
    for (final TimelineEvent event in events) {
      if (event.phase == 'B') {
        begin = event;
      } else {
        if (begin != null) {
          result.add(extractor(begin, event));
          // each begin only gets used once.
          begin = null;
        }
      }
    }

    return result;
  }

  /// Extracts Duration list that are reported as a pair of begin/end events.
  ///
  /// Extracts Duration of events by looking for events with the name and phase
  /// begin ("ph": "B"). This routine assumes that the next event with the same
  /// name is phase end ("ph": "E"), but it's not examined.
  /// "SceneDisplayLag" event is an exception, with phase ("ph") labeled
  /// 'b' and 'e', meaning begin and end phase for an async event.
  /// See [SceneDisplayLagSummarizer].
  /// See: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
  List<Duration> _extractBeginEndEvents(String name) {
    return _extractDurations(
      name,
      (TimelineEvent beginEvent, TimelineEvent endEvent) {
        return Duration(microseconds: endEvent.timestampMicros - beginEvent.timestampMicros);
      },
    );
  }

  List<Duration> _extractBeginTimestamps(String name) {
    final List<Duration> result = _extractDurations(
      name,
      (TimelineEvent beginEvent, TimelineEvent endEvent) {
        return Duration(microseconds: beginEvent.timestampMicros);
      },
    );

    // Align timestamps so the first event is at 0.
    for (int i = result.length - 1; i >= 0; i -= 1) {
      result[i] = result[i] - result[0];
    }
    return result;
  }

  double _averageInMillis(Iterable<Duration> durations) {
    if (durations.isEmpty)
      throw ArgumentError('durations is empty!');
    final double total = durations.fold<double>(0.0, (double t, Duration duration) => t + duration.inMicroseconds.toDouble() / 1000.0);
    return total / durations.length;
  }

  double _percentileInMillis(Iterable<Duration> durations, double percentile) {
    if (durations.isEmpty)
      throw ArgumentError('durations is empty!');
    assert(percentile >= 0.0 && percentile <= 100.0);
    final List<double> doubles = durations.map<double>((Duration duration) => duration.inMicroseconds.toDouble() / 1000.0).toList();
    return findPercentile(doubles, percentile);
  }

  double _maxInMillis(Iterable<Duration> durations) {
    if (durations.isEmpty)
      throw ArgumentError('durations is empty!');
    return durations
        .map<double>((Duration duration) => duration.inMicroseconds.toDouble() / 1000.0)
        .reduce(math.max);
  }

  SceneDisplayLagSummarizer _sceneDisplayLagSummarizer() => SceneDisplayLagSummarizer(_extractNamedEvents(kSceneDisplayLagEvent));

  List<Duration> _extractGpuRasterizerDrawDurations() => _extractBeginEndEvents(kRasterizeFrameEventName);

  ProfilingSummarizer _profilingSummarizer() => ProfilingSummarizer.fromEvents(_extractEventsWithNames(kProfilingEvents));

  List<Duration> _extractFrameDurations() => _extractBeginEndEvents(kBuildFrameEventName);
}
