// 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:math' as math;
import 'dart:ui';

import 'recorder.dart';
import 'test_data.dart';

/// Draws 9 screens worth of text in a 3x3 grid with only the middle cell
/// appearing on the visible screen:
///
///     +-------------+-------------+-------------+
///     |             |             |             |
///     |  invisible  |  invisible  |  invisible  |
///     |             |             |             |
///     +-----------------------------------------+
///     |             |             |             |
///     |  invisible  |   visible   |  invisible  |
///     |             |             |             |
///     +-----------------------------------------+
///     |             |             |             |
///     |  invisible  |  invisible  |  invisible  |
///     |             |             |             |
///     +-------------+-------------+-------------+
///
/// This reproduces the bug where we render more than visible causing
/// performance issues: https://github.com/flutter/flutter/issues/48516
class BenchTextOutOfPictureBounds extends SceneBuilderRecorder {
  BenchTextOutOfPictureBounds() : super(name: benchmarkName) {
    const Color red = Color.fromARGB(255, 255, 0, 0);
    const Color green = Color.fromARGB(255, 0, 255, 0);

    // We don't want paragraph generation and layout to pollute benchmark numbers.
    singleLineParagraphs = generateLaidOutParagraphs(
      paragraphCount: 500,
      minWordCountPerParagraph: 2,
      maxWordCountPerParagraph: 4,
      widthConstraint: view.physicalSize.width / 2,
      color: red,
    );
    multiLineParagraphs = generateLaidOutParagraphs(
      paragraphCount: 50,
      minWordCountPerParagraph: 30,
      maxWordCountPerParagraph: 49,
      widthConstraint: view.physicalSize.width / 2,
      color: green,
    );
  }

  // Use hard-coded seed to make sure the data is stable across benchmark runs.
  static final math.Random _random = math.Random(0);

  static const String benchmarkName = 'text_out_of_picture_bounds';

  late List<Paragraph> singleLineParagraphs;
  late List<Paragraph> multiLineParagraphs;

  @override
  void onDrawFrame(SceneBuilder sceneBuilder) {
    final PictureRecorder pictureRecorder = PictureRecorder();
    final Canvas canvas = Canvas(pictureRecorder);
    final Size viewSize = view.physicalSize;
    const double padding = 10.0;

    // Fills a single cell with random text.
    void fillCellWithText(List<Paragraph> textSource) {
      canvas.save();
      double topOffset = 0;
      while (topOffset < viewSize.height) {
        final Paragraph paragraph =
            textSource[_random.nextInt(textSource.length)];

        // Give it enough space to make sure it ends up being a single-line paragraph.
        paragraph.layout(ParagraphConstraints(width: viewSize.width / 2));

        canvas.drawParagraph(paragraph, Offset.zero);
        canvas.translate(0, paragraph.height + padding);
        topOffset += paragraph.height + padding;
      }
      canvas.restore();
    }

    // Starting with the top-left cell, fill every cell with text.
    canvas.translate(-viewSize.width, -viewSize.height);
    for (int row = 0; row < 3; row++) {
      canvas.save();
      for (int col = 0; col < 3; col++) {
        canvas.drawRect(
          Offset.zero & viewSize,
          Paint()
            ..style = PaintingStyle.stroke
            ..strokeWidth = 2.0,
        );
        // Fill single-line text.
        fillCellWithText(singleLineParagraphs);

        // Fill multi-line text.
        canvas.save();
        canvas.translate(viewSize.width / 2, 0);
        fillCellWithText(multiLineParagraphs);
        canvas.restore();

        // Shift to next column.
        canvas.translate(viewSize.width, 0);
      }

      // Undo horizontal shift.
      canvas.restore();

      // Shift to next row.
      canvas.translate(0, viewSize.height);
    }

    final Picture picture = pictureRecorder.endRecording();
    sceneBuilder.pushOffset(0.0, 0.0);
    sceneBuilder.addPicture(Offset.zero, picture);
    sceneBuilder.pop();
  }
}
