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

#include "flutter/flow/layers/performance_overlay_layer.h"

#include <iomanip>
#include <iostream>
#include <memory>
#include <string>

#include "flow/stopwatch.h"
#include "flow/stopwatch_dl.h"
#include "flow/stopwatch_sk.h"
#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkTextBlob.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "txt/platform.h"
#ifdef IMPELLER_SUPPORTS_RENDERING
#include "impeller/typographer/backends/skia/text_frame_skia.h"  // nogncheck
#endif  // IMPELLER_SUPPORTS_RENDERING

namespace flutter {
namespace {

void VisualizeStopWatch(DlCanvas* canvas,
                        const bool impeller_enabled,
                        const Stopwatch& stopwatch,
                        SkScalar x,
                        SkScalar y,
                        SkScalar width,
                        SkScalar height,
                        bool show_graph,
                        bool show_labels,
                        const std::string& label_prefix,
                        const std::string& font_path) {
  const int label_x = 8;    // distance from x
  const int label_y = -10;  // distance from y+height

  if (show_graph) {
    SkRect visualization_rect = SkRect::MakeXYWH(x, y, width, height);
    std::unique_ptr<StopwatchVisualizer> visualizer;

    if (impeller_enabled) {
      visualizer = std::make_unique<DlStopwatchVisualizer>(stopwatch);
    } else {
      visualizer = std::make_unique<SkStopwatchVisualizer>(stopwatch);
    }

    visualizer->Visualize(canvas, visualization_rect);
  }

  if (show_labels) {
    auto text = PerformanceOverlayLayer::MakeStatisticsText(
        stopwatch, label_prefix, font_path);
    // Historically SK_ColorGRAY (== 0xFF888888) was used here
    DlPaint paint(DlColor(0xFF888888));
#ifdef IMPELLER_SUPPORTS_RENDERING
    if (impeller_enabled) {
      canvas->DrawTextFrame(impeller::MakeTextFrameFromTextBlobSkia(text),
                            x + label_x, y + height + label_y, paint);
      return;
    }
#endif  // IMPELLER_SUPPORTS_RENDERING
    canvas->DrawTextBlob(text, x + label_x, y + height + label_y, paint);
  }
}

}  // namespace

sk_sp<SkTextBlob> PerformanceOverlayLayer::MakeStatisticsText(
    const Stopwatch& stopwatch,
    const std::string& label_prefix,
    const std::string& font_path) {
  SkFont font;
  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
  if (font_path == "") {
    if (sk_sp<SkTypeface> face = font_mgr->matchFamilyStyle(nullptr, {})) {
      font = SkFont(face, 15);
    } else {
      // In Skia's Android fontmgr, matchFamilyStyle can return null instead
      // of falling back to a default typeface. If that's the case, we can use
      // legacyMakeTypeface, which *does* use that default typeface.
      font = SkFont(font_mgr->legacyMakeTypeface(nullptr, {}), 15);
    }
  } else {
    font = SkFont(font_mgr->makeFromFile(font_path.c_str()), 15);
  }
  // Make sure there's not an empty typeface returned, or we won't see any text.
  FML_DCHECK(font.getTypeface()->countGlyphs() > 0);

  double max_ms_per_frame = stopwatch.MaxDelta().ToMillisecondsF();
  double average_ms_per_frame = stopwatch.AverageDelta().ToMillisecondsF();
  std::stringstream stream;
  stream.setf(std::ios::fixed | std::ios::showpoint);
  stream << std::setprecision(1);
  stream << label_prefix << "  "
         << "max " << max_ms_per_frame << " ms/frame, "
         << "avg " << average_ms_per_frame << " ms/frame";
  auto text = stream.str();
  return SkTextBlob::MakeFromText(text.c_str(), text.size(), font,
                                  SkTextEncoding::kUTF8);
}

PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options,
                                                 const char* font_path)
    : options_(options) {
  if (font_path != nullptr) {
    font_path_ = font_path;
  }
}

void PerformanceOverlayLayer::Diff(DiffContext* context,
                                   const Layer* old_layer) {
  DiffContext::AutoSubtreeRestore subtree(context);
  if (!context->IsSubtreeDirty()) {
    FML_DCHECK(old_layer);
    auto prev = old_layer->as_performance_overlay_layer();
    context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(prev));
  }
  context->AddLayerBounds(paint_bounds());
  context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
}

void PerformanceOverlayLayer::Paint(PaintContext& context) const {
  const int padding = 8;

  if (!options_) {
    return;
  }

  SkScalar x = paint_bounds().x() + padding;
  SkScalar y = paint_bounds().y() + padding;
  SkScalar width = paint_bounds().width() - (padding * 2);
  SkScalar height = paint_bounds().height() / 2;
  auto mutator = context.state_stack.save();

  VisualizeStopWatch(
      context.canvas, context.impeller_enabled, context.raster_time, x, y,
      width, height - padding, options_ & kVisualizeRasterizerStatistics,
      options_ & kDisplayRasterizerStatistics, "Raster", font_path_);

  VisualizeStopWatch(context.canvas, context.impeller_enabled, context.ui_time,
                     x, y + height, width, height - padding,
                     options_ & kVisualizeEngineStatistics,
                     options_ & kDisplayEngineStatistics, "UI", font_path_);
}

}  // namespace flutter
