// 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 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'package:vector_math/vector_math_64.dart';

import '../common.dart';

const int _kNumIterations = 10000000;
const int _kNumWarmUp = 100000;

void main() {
  assert(false, "Don't run benchmarks in checked mode! Use 'flutter run --release'.");
  print('MatrixUtils.transformRect and .transformPoint benchmark...');

  Matrix4 _makePerspective(double radius, double angle, double perspective) {
    return MatrixUtils.createCylindricalProjectionTransform(
      radius: radius,
      angle: angle,
      perspective: perspective,
    );
  }

  final List<Matrix4> _affineTransforms = <Matrix4>[
    Matrix4.identity()..scale(1.2, 1.3, 1.0)..rotateZ(0.1),
    Matrix4.identity()..translate(12.0, 13.0, 10.0),
    Matrix4.identity()..scale(1.2, 1.3, 1.0)..translate(12.0, 13.0, 10.0),
  ];
  final List<Matrix4> _perspectiveTransforms = <Matrix4>[
    _makePerspective(10.0, math.pi / 8.0, 0.3),
    _makePerspective( 8.0, math.pi / 8.0, 0.2),
    _makePerspective( 1.0, math.pi / 4.0, 0.1)..rotateX(0.1),
  ];
  final List<Rect> _rectangles = <Rect>[
    const Rect.fromLTRB(1.1, 1.2, 1.5, 1.8),
    const Rect.fromLTRB(1.1, 1.2, 0.0, 1.0),
    const Rect.fromLTRB(1.1, 1.2, 1.3, 1.0),
    const Rect.fromLTRB(-1.1, -1.2, 0.0, 1.0),
    const Rect.fromLTRB(-1.1, -1.2, -1.5, -1.8),
  ];
  final List<Offset> _offsets = <Offset>[
    const Offset(1.1, 1.2),
    const Offset(1.5, 1.8),
    const Offset(0.0, 0.0),
    const Offset(-1.1, -1.2),
    const Offset(-1.5, -1.8),
  ];
  final int nAffine = _affineTransforms.length;
  final int nPerspective = _perspectiveTransforms.length;
  final int nRectangles = _rectangles.length;
  final int nOffsets = _offsets.length;

  // Warm up lap
  for (int i = 0; i < _kNumWarmUp; i += 1) {
    final Matrix4 transform = _perspectiveTransforms[i % nPerspective];
    final Rect rect = _rectangles[(i ~/ nPerspective) % nRectangles];
    final Offset offset = _offsets[(i ~/ nPerspective) % nOffsets];
    MatrixUtils.transformRect(transform, rect);
    MatrixUtils.transformPoint(transform, offset);
  }
  for (int i = 0; i < _kNumWarmUp; i += 1) {
    final Matrix4 transform = _affineTransforms[i % nAffine];
    final Rect rect = _rectangles[(i ~/ nAffine) % nRectangles];
    final Offset offset = _offsets[(i ~/ nAffine) % nOffsets];
    MatrixUtils.transformRect(transform, rect);
    MatrixUtils.transformPoint(transform, offset);
  }

  final Stopwatch watch = Stopwatch();
  watch.start();
  for (int i = 0; i < _kNumIterations; i += 1) {
    final Matrix4 transform = _perspectiveTransforms[i % nPerspective];
    final Rect rect = _rectangles[(i ~/ nPerspective) % nRectangles];
    MatrixUtils.transformRect(transform, rect);
  }
  watch.stop();
  final int rectMicrosecondsPerspective = watch.elapsedMicroseconds;

  watch.reset();
  watch.start();
  for (int i = 0; i < _kNumIterations; i += 1) {
    final Matrix4 transform = _affineTransforms[i % nAffine];
    final Rect rect = _rectangles[(i ~/ nAffine) % nRectangles];
    MatrixUtils.transformRect(transform, rect);
  }
  watch.stop();
  final int rectMicrosecondsAffine = watch.elapsedMicroseconds;

  watch.reset();
  watch.start();
  for (int i = 0; i < _kNumIterations; i += 1) {
    final Matrix4 transform = _perspectiveTransforms[i % nPerspective];
    final Offset offset = _offsets[(i ~/ nPerspective) % nOffsets];
    MatrixUtils.transformPoint(transform, offset);
  }
  watch.stop();
  final int pointMicrosecondsPerspective = watch.elapsedMicroseconds;

  watch.reset();
  watch.start();
  for (int i = 0; i < _kNumIterations; i += 1) {
    final Matrix4 transform = _affineTransforms[i % nAffine];
    final Offset offset = _offsets[(i ~/ nAffine) % nOffsets];
    MatrixUtils.transformPoint(transform, offset);
  }
  watch.stop();
  final int pointMicrosecondsAffine = watch.elapsedMicroseconds;

  final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
  const double scale = 1000.0 / _kNumIterations;
  printer.addResult(
    description: 'MatrixUtils.transformRectPerspective',
    value: rectMicrosecondsPerspective * scale,
    unit: 'ns per iteration',
    name: 'MatrixUtils_persp_transformRect_iteration',
  );
  printer.addResult(
    description: 'MatrixUtils.transformRectAffine',
    value: rectMicrosecondsAffine * scale,
    unit: 'ns per iteration',
    name: 'MatrixUtils_affine_transformRect_iteration',
  );
  printer.addResult(
    description: 'MatrixUtils.transformPointPerspective',
    value: pointMicrosecondsPerspective * scale,
    unit: 'ns per iteration',
    name: 'MatrixUtils_persp_transformPoint_iteration',
  );
  printer.addResult(
    description: 'MatrixUtils.transformPointAffine',
    value: pointMicrosecondsAffine * scale,
    unit: 'ns per iteration',
    name: 'MatrixUtils_affine_transformPoint_iteration',
  );
  printer.printToStdout();
}
