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

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';

import 'rendering_tester.dart';

void main() {
  TestRenderingFlutterBinding.ensureInitialized();

  test('PipelineOwner dispatches memory events', () async {
    await expectLater(
      await memoryEvents(() => PipelineOwner().dispose(), PipelineOwner),
      areCreateAndDispose,
    );
  });

  test('nodesNeedingLayout updated with layout changes', () {
    final owner = _TestPipelineOwner();
    final renderObject = TestRenderObject()..isRepaintBoundary = true;
    renderObject.attach(owner);
    expect(owner.needLayout, isEmpty);

    renderObject.layout(const BoxConstraints.tightForFinite());
    renderObject.markNeedsLayout();
    expect(owner.needLayout, contains(renderObject));

    owner.flushLayout();
    expect(owner.needLayout, isEmpty);
  });

  test('nodesNeedingPaint updated with paint changes', () {
    final owner = _TestPipelineOwner();
    final renderObject = TestRenderObject(allowPaintBounds: true)..isRepaintBoundary = true;
    final layer = OffsetLayer();
    layer.attach(owner);
    renderObject.attach(owner);
    expect(owner.needPaint, isEmpty);

    renderObject.markNeedsPaint();
    renderObject.scheduleInitialPaint(layer);
    expect(owner.needPaint, contains(renderObject));

    owner.flushPaint();
    expect(owner.needPaint, isEmpty);
  });

  test('ensure frame is scheduled for markNeedsSemanticsUpdate', () {
    // Initialize all bindings because owner.flushSemantics() requires a window
    final renderObject = TestRenderObject();
    var onNeedVisualUpdateCallCount = 0;
    final owner = PipelineOwner(
      onNeedVisualUpdate: () {
        onNeedVisualUpdateCallCount += 1;
      },
      onSemanticsUpdate: (ui.SemanticsUpdate update) {},
    );
    owner.ensureSemantics();
    owner.rootNode = renderObject;
    renderObject.layout(
      const BoxConstraints.tightForFinite(),
    ); // semantics are only calculated if layout information is up to date.
    owner.flushSemantics();

    expect(onNeedVisualUpdateCallCount, 1);
    renderObject.markNeedsSemanticsUpdate();
    expect(onNeedVisualUpdateCallCount, 2);
  });

  test('onSemanticsUpdate is called during flushSemantics.', () {
    var onSemanticsUpdateCallCount = 0;
    final owner = PipelineOwner(
      onSemanticsUpdate: (ui.SemanticsUpdate update) {
        onSemanticsUpdateCallCount += 1;
      },
    );
    owner.ensureSemantics();

    expect(onSemanticsUpdateCallCount, 0);

    final renderObject = TestRenderObject();
    owner.rootNode = renderObject;
    renderObject.layout(const BoxConstraints.tightForFinite());
    owner.flushSemantics();

    expect(onSemanticsUpdateCallCount, 1);
  });

  test('Enabling semantics without configuring onSemanticsUpdate is invalid.', () {
    final pipelineOwner = PipelineOwner();
    expect(() => pipelineOwner.ensureSemantics(), throwsAssertionError);
  });

  test('onSemanticsUpdate during sendSemanticsUpdate.', () {
    var onSemanticsUpdateCallCount = 0;
    final owner = SemanticsOwner(
      onSemanticsUpdate: (ui.SemanticsUpdate update) {
        onSemanticsUpdateCallCount += 1;
      },
    );

    final node = SemanticsNode.root(owner: owner);
    node.rect = Rect.largest;

    expect(onSemanticsUpdateCallCount, 0);

    owner.sendSemanticsUpdate();

    expect(onSemanticsUpdateCallCount, 1);
  });

  test('detached RenderObject does not do semantics', () {
    final renderObject = TestRenderObject();
    expect(renderObject.attached, isFalse);
    expect(renderObject.describeSemanticsConfigurationCallCount, 0);

    renderObject.markNeedsSemanticsUpdate();
    expect(renderObject.describeSemanticsConfigurationCallCount, 0);
  });

  test('ensure errors processing render objects are well formatted', () {
    late FlutterErrorDetails errorDetails;
    final FlutterExceptionHandler? oldHandler = FlutterError.onError;
    FlutterError.onError = (FlutterErrorDetails details) {
      errorDetails = details;
    };
    final owner = PipelineOwner();
    final renderObject = TestThrowingRenderObject();
    try {
      renderObject.attach(owner);
      renderObject.layout(const BoxConstraints());
    } finally {
      FlutterError.onError = oldHandler;
    }

    expect(errorDetails, isNotNull);
    expect(errorDetails.stack, isNotNull);
    // Check the ErrorDetails without the stack trace
    final List<String> lines = errorDetails.toString().split('\n');
    // The lines in the middle of the error message contain the stack trace
    // which will change depending on where the test is run.
    expect(lines.length, greaterThan(8));
    expect(
      lines.take(4).join('\n'),
      equalsIgnoringHashCodes(
        '══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞══════════════════════\n'
        'The following assertion was thrown during performLayout():\n'
        'TestThrowingRenderObject does not support performLayout.\n',
      ),
    );

    expect(
      lines.getRange(lines.length - 8, lines.length).join('\n'),
      equalsIgnoringHashCodes(
        '\n'
        'The following RenderObject was being processed when the exception was fired:\n'
        '  TestThrowingRenderObject#00000 NEEDS-PAINT:\n'
        '  parentData: MISSING\n'
        '  constraints: BoxConstraints(unconstrained)\n'
        'This RenderObject has no descendants.\n'
        '═════════════════════════════════════════════════════════════════\n',
      ),
    );
  });

  test('ContainerParentDataMixin requires nulled out pointers to siblings before detach', () {
    expect(() => TestParentData().detach(), isNot(throwsAssertionError));

    final data1 = TestParentData()
      ..nextSibling = RenderOpacity()
      ..previousSibling = RenderOpacity();
    expect(() => data1.detach(), throwsAssertionError);

    final data2 = TestParentData()..previousSibling = RenderOpacity();
    expect(() => data2.detach(), throwsAssertionError);

    final data3 = TestParentData()..nextSibling = RenderOpacity();
    expect(() => data3.detach(), throwsAssertionError);
  });

  test('RenderObject.getTransformTo asserts if target not in the same render tree', () {
    final owner = PipelineOwner();
    final renderObject1 = TestRenderObject();
    renderObject1.attach(owner);
    final renderObject2 = TestRenderObject();
    renderObject2.attach(owner);
    expect(() => renderObject1.getTransformTo(renderObject2), throwsAssertionError);
  });

  test('RenderObject.getTransformTo works for siblings and descendants', () {
    final owner = PipelineOwner();
    final renderObject1 = TestRenderObject()..attach(owner);
    final renderObject11 = TestRenderObject();
    final renderObject12 = TestRenderObject();

    renderObject1
      ..add(renderObject11)
      ..add(renderObject12);
    expect(renderObject11.getTransformTo(renderObject12), equals(Matrix4.identity()));
    expect(renderObject1.getTransformTo(renderObject11), equals(Matrix4.identity()));
    expect(renderObject1.getTransformTo(renderObject12), equals(Matrix4.identity()));
    expect(renderObject11.getTransformTo(renderObject1), equals(Matrix4.identity()));
    expect(renderObject12.getTransformTo(renderObject1), equals(Matrix4.identity()));

    expect(renderObject1.getTransformTo(renderObject1), equals(Matrix4.identity()));
    expect(renderObject11.getTransformTo(renderObject11), equals(Matrix4.identity()));
    expect(renderObject12.getTransformTo(renderObject12), equals(Matrix4.identity()));
  });

  test('RenderObject.getTransformTo gets the correct paint transform', () {
    final owner = PipelineOwner();
    final renderObject0 = TestRenderObject()..attach(owner);
    final renderObject1 = TestRenderObject();
    final renderObject2 = TestRenderObject();
    renderObject0
      ..add(renderObject1)
      ..add(renderObject2)
      ..paintTransform = Matrix4.diagonal3Values(9, 4, 1);

    final renderObject11 = TestRenderObject();
    final renderObject21 = TestRenderObject();
    renderObject1
      ..add(renderObject11)
      ..paintTransform = Matrix4.translationValues(8, 16, 32);
    renderObject2
      ..add(renderObject21)
      ..paintTransform = Matrix4.translationValues(32, 64, 128);

    expect(
      renderObject11.getTransformTo(renderObject21),
      equals(Matrix4.translationValues((8 - 32) * 9, (16 - 64) * 4, 32 - 128)),
    );
    // Turn one of the paint transforms into a singular matrix and getTransformTo
    // should return Matrix4.zero().
    renderObject0.paintTransform = Matrix4(
      1,
      1,
      1,
      1,
      2,
      2,
      2,
      2,
      3,
      3,
      3,
      3,
      4,
      4,
      4,
      4,
    ); // Not a full rank matrix, so it has to be singular.
    expect(renderObject11.getTransformTo(renderObject21), equals(Matrix4.zero()));
  });

  test('PaintingContext.pushClipRect reuses the layer', () {
    _testPaintingContextLayerReuse<ClipRectLayer>((
      PaintingContextCallback painter,
      PaintingContext context,
      Offset offset,
      Layer? oldLayer,
    ) {
      return context.pushClipRect(
        true,
        offset,
        Rect.zero,
        painter,
        oldLayer: oldLayer as ClipRectLayer?,
      );
    });
  });

  test('PaintingContext.pushClipRRect reuses the layer', () {
    _testPaintingContextLayerReuse<ClipRRectLayer>((
      PaintingContextCallback painter,
      PaintingContext context,
      Offset offset,
      Layer? oldLayer,
    ) {
      return context.pushClipRRect(
        true,
        offset,
        Rect.zero,
        RRect.fromRectAndRadius(Rect.zero, const Radius.circular(1.0)),
        painter,
        oldLayer: oldLayer as ClipRRectLayer?,
      );
    });
  });

  test('PaintingContext.pushClipRSuperellipse reuses the layer', () {
    _testPaintingContextLayerReuse<ClipRSuperellipseLayer>((
      PaintingContextCallback painter,
      PaintingContext context,
      Offset offset,
      Layer? oldLayer,
    ) {
      return context.pushClipRSuperellipse(
        true,
        offset,
        Rect.zero,
        RSuperellipse.fromRectAndRadius(Rect.zero, const Radius.circular(1.0)),
        painter,
        oldLayer: oldLayer as ClipRSuperellipseLayer?,
      );
    });
  });

  test('PaintingContext.pushClipPath reuses the layer', () {
    _testPaintingContextLayerReuse<ClipPathLayer>((
      PaintingContextCallback painter,
      PaintingContext context,
      Offset offset,
      Layer? oldLayer,
    ) {
      return context.pushClipPath(
        true,
        offset,
        Rect.zero,
        Path(),
        painter,
        oldLayer: oldLayer as ClipPathLayer?,
      );
    });
  });

  test('PaintingContext.pushColorFilter reuses the layer', () {
    _testPaintingContextLayerReuse<ColorFilterLayer>((
      PaintingContextCallback painter,
      PaintingContext context,
      Offset offset,
      Layer? oldLayer,
    ) {
      return context.pushColorFilter(
        offset,
        const ColorFilter.mode(Color.fromRGBO(0, 0, 0, 1.0), BlendMode.clear),
        painter,
        oldLayer: oldLayer as ColorFilterLayer?,
      );
    });
  });

  test('PaintingContext.pushTransform reuses the layer', () {
    _testPaintingContextLayerReuse<TransformLayer>((
      PaintingContextCallback painter,
      PaintingContext context,
      Offset offset,
      Layer? oldLayer,
    ) {
      return context.pushTransform(
        true,
        offset,
        Matrix4.identity(),
        painter,
        oldLayer: oldLayer as TransformLayer?,
      );
    });
  });

  test('PaintingContext.pushOpacity reuses the layer', () {
    _testPaintingContextLayerReuse<OpacityLayer>((
      PaintingContextCallback painter,
      PaintingContext context,
      Offset offset,
      Layer? oldLayer,
    ) {
      return context.pushOpacity(offset, 100, painter, oldLayer: oldLayer as OpacityLayer?);
    });
  });

  test('RenderObject.dispose sets debugDisposed to true', () {
    final renderObject = TestRenderObject();
    expect(renderObject.debugDisposed, false);
    renderObject.dispose();
    expect(renderObject.debugDisposed, true);
    expect(renderObject.toStringShort(), contains('DISPOSED'));
  });

  test('Leader layer can switch to a different render object within one frame', () {
    List<FlutterErrorDetails?>? caughtErrors;
    TestRenderingFlutterBinding.instance.onErrors = () {
      caughtErrors = TestRenderingFlutterBinding.instance.takeAllFlutterErrorDetails().toList();
    };

    final layerLink = LayerLink();
    // renderObject1 paints the leader layer first.
    final renderObject1 = LeaderLayerRenderObject();
    renderObject1.layerLink = layerLink;
    renderObject1.attach(TestRenderingFlutterBinding.instance.pipelineOwner);
    final rootLayer1 = OffsetLayer();
    rootLayer1.attach(renderObject1);
    renderObject1.scheduleInitialPaint(rootLayer1);
    renderObject1.layout(const BoxConstraints.tightForFinite());

    final renderObject2 = LeaderLayerRenderObject();
    final rootLayer2 = OffsetLayer();
    rootLayer2.attach(renderObject2);
    renderObject2.attach(TestRenderingFlutterBinding.instance.pipelineOwner);
    renderObject2.scheduleInitialPaint(rootLayer2);
    renderObject2.layout(const BoxConstraints.tightForFinite());
    TestRenderingFlutterBinding.instance.pumpCompleteFrame();

    // Swap the layer link to renderObject2 in the same frame
    renderObject1.layerLink = null;
    renderObject1.markNeedsPaint();
    renderObject2.layerLink = layerLink;
    renderObject2.markNeedsPaint();
    TestRenderingFlutterBinding.instance.pumpCompleteFrame();

    // Swap the layer link to renderObject1 in the same frame
    renderObject1.layerLink = layerLink;
    renderObject1.markNeedsPaint();
    renderObject2.layerLink = null;
    renderObject2.markNeedsPaint();
    TestRenderingFlutterBinding.instance.pumpCompleteFrame();

    TestRenderingFlutterBinding.instance.onErrors = null;
    expect(caughtErrors, isNull);
  });

  test('Leader layer append to two render objects does crash', () {
    List<FlutterErrorDetails?>? caughtErrors;
    TestRenderingFlutterBinding.instance.onErrors = () {
      caughtErrors = TestRenderingFlutterBinding.instance.takeAllFlutterErrorDetails().toList();
    };
    final layerLink = LayerLink();
    // renderObject1 paints the leader layer first.
    final renderObject1 = LeaderLayerRenderObject();
    renderObject1.layerLink = layerLink;
    renderObject1.attach(TestRenderingFlutterBinding.instance.pipelineOwner);
    final rootLayer1 = OffsetLayer();
    rootLayer1.attach(renderObject1);
    renderObject1.scheduleInitialPaint(rootLayer1);
    renderObject1.layout(const BoxConstraints.tightForFinite());

    final renderObject2 = LeaderLayerRenderObject();
    renderObject2.layerLink = layerLink;
    final rootLayer2 = OffsetLayer();
    rootLayer2.attach(renderObject2);
    renderObject2.attach(TestRenderingFlutterBinding.instance.pipelineOwner);
    renderObject2.scheduleInitialPaint(rootLayer2);
    renderObject2.layout(const BoxConstraints.tightForFinite());
    TestRenderingFlutterBinding.instance.pumpCompleteFrame();

    TestRenderingFlutterBinding.instance.onErrors = null;
    expect(caughtErrors!.isNotEmpty, isTrue);
  });

  test('RenderObject.dispose null the layer on repaint boundaries', () {
    final renderObject = TestRenderObject(allowPaintBounds: true);
    // Force a layer to get set.
    renderObject.isRepaintBoundary = true;
    PaintingContext.repaintCompositedChild(renderObject, debugAlsoPaintedParent: true);
    expect(renderObject.debugLayer, isA<OffsetLayer>());

    // Dispose with repaint boundary still being true.
    renderObject.dispose();
    expect(renderObject.debugLayer, null);
  });

  test('RenderObject.dispose nulls the layer on non-repaint boundaries', () {
    final renderObject = TestRenderObject(allowPaintBounds: true);
    // Force a layer to get set.
    renderObject.isRepaintBoundary = true;
    PaintingContext.repaintCompositedChild(renderObject, debugAlsoPaintedParent: true);

    // Dispose with repaint boundary being false.
    renderObject.isRepaintBoundary = false;
    renderObject.dispose();
    expect(renderObject.debugLayer, null);
  });

  test('Add composition callback works', () {
    final root = ContainerLayer();
    final context = PaintingContext(root, Rect.zero);
    var calledBack = false;
    final object = TestObservingRenderObject((Layer layer) {
      expect(layer, root);
      calledBack = true;
    });

    expect(calledBack, false);
    object.paint(context, Offset.zero);
    expect(calledBack, false);

    root.buildScene(ui.SceneBuilder()).dispose();
    expect(calledBack, true);
  });

  test('Change isRepaintBoundary after both markNeedsCompositedLayerUpdate and markNeedsPaint', () {
    List<FlutterErrorDetails?>? caughtErrors;
    TestRenderingFlutterBinding.instance.onErrors = () {
      caughtErrors = TestRenderingFlutterBinding.instance.takeAllFlutterErrorDetails().toList();
    };
    final object = TestRenderObject(allowPaintBounds: true);
    object.isRepaintBoundary = true;
    object.attach(TestRenderingFlutterBinding.instance.pipelineOwner);
    object.layout(const BoxConstraints.tightForFinite());
    PaintingContext.repaintCompositedChild(object, debugAlsoPaintedParent: true);

    object.markNeedsCompositedLayerUpdate();
    object.markNeedsPaint();
    object.isRepaintBoundary = false;
    object.markNeedsCompositingBitsUpdate();
    TestRenderingFlutterBinding.instance.pumpCompleteFrame();
    expect(caughtErrors, isNull);
  });

  test('ContainerParentDataMixin asserts parentData type', () {
    final TestRenderObject renderObject = TestRenderObjectWithoutSetupParentData();
    final child = TestRenderObject();
    expect(
      () => renderObject.add(child),
      throwsA(
        isA<AssertionError>().having(
          (AssertionError error) => error.toString(),
          'description',
          contains(
            'A child of TestRenderObjectWithoutSetupParentData has parentData of type ParentData, '
            'which does not conform to TestRenderObjectParentData. Class using ContainerRenderObjectMixin '
            'should override setupParentData() to set parentData to type TestRenderObjectParentData.',
          ),
        ),
      ),
    );
  });

  test('PictureRecorder getter', () {
    final context = PaintingContext(ContainerLayer(), Rect.zero);
    expect(context.recorder.isRecording, isTrue);
  });
}

class TestObservingRenderObject extends RenderBox {
  TestObservingRenderObject(this.callback);

  final CompositionCallback callback;

  @override
  bool get sizedByParent => true;

  @override
  void paint(PaintingContext context, Offset offset) {
    context.addCompositionCallback(callback);
  }
}

// Tests the create-update cycle by pumping two frames. The first frame has no
// prior layer and forces the painting context to create a new one. The second
// frame reuses the layer painted on the first frame.
void _testPaintingContextLayerReuse<L extends Layer>(_LayerTestPaintCallback painter) {
  final box = _TestCustomLayerBox(painter);
  layout(box, phase: EnginePhase.paint);

  // Force a repaint. Otherwise, pumpFrame is a noop.
  box.markNeedsPaint();
  pumpFrame(phase: EnginePhase.paint);
  expect(box.paintedLayers, hasLength(2));
  expect(box.paintedLayers[0], isA<L>());
  expect(box.paintedLayers[0], same(box.paintedLayers[1]));
}

typedef _LayerTestPaintCallback =
    Layer? Function(
      PaintingContextCallback painter,
      PaintingContext context,
      Offset offset,
      Layer? oldLayer,
    );

class _TestCustomLayerBox extends RenderBox {
  _TestCustomLayerBox(this.painter);

  final _LayerTestPaintCallback painter;
  final List<Layer> paintedLayers = <Layer>[];

  @override
  bool get isRepaintBoundary => false;

  @override
  void performLayout() {
    size = constraints.smallest;
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    final Layer paintedLayer = painter(super.paint, context, offset, layer)!;
    paintedLayers.add(paintedLayer);
    layer = paintedLayer as ContainerLayer;
  }
}

class TestParentData extends ParentData with ContainerParentDataMixin<RenderBox> {}

class TestRenderObjectParentData extends ParentData
    with ContainerParentDataMixin<TestRenderObject> {}

class TestRenderObject extends RenderObject
    with ContainerRenderObjectMixin<TestRenderObject, TestRenderObjectParentData> {
  TestRenderObject({this.allowPaintBounds = false});

  final bool allowPaintBounds;

  @override
  bool isRepaintBoundary = false;

  @override
  void debugAssertDoesMeetConstraints() {}

  @override
  Rect get paintBounds {
    assert(allowPaintBounds); // For some tests, this should not get called.
    return Rect.zero;
  }

  Matrix4 paintTransform = Matrix4.identity();
  @override
  void applyPaintTransform(covariant RenderObject child, Matrix4 transform) {
    super.applyPaintTransform(child, transform);
    transform.multiply(paintTransform);
  }

  @override
  void setupParentData(RenderObject child) {
    if (child.parentData is! TestRenderObjectParentData) {
      child.parentData = TestRenderObjectParentData();
    }
  }

  @override
  void performLayout() {}

  @override
  void performResize() {}

  @override
  Rect get semanticBounds => const Rect.fromLTWH(0.0, 0.0, 10.0, 20.0);

  int describeSemanticsConfigurationCallCount = 0;

  @override
  void describeSemanticsConfiguration(SemanticsConfiguration config) {
    super.describeSemanticsConfiguration(config);
    config.isSemanticBoundary = true;
    describeSemanticsConfigurationCallCount++;
  }
}

class TestRenderObjectWithoutSetupParentData extends TestRenderObject {
  @override
  void setupParentData(RenderObject child) {
    // Use a mismatched parent data type.
    if (child.parentData is! ParentData) {
      child.parentData = ParentData();
    }
  }
}

class LeaderLayerRenderObject extends RenderObject {
  LeaderLayerRenderObject();

  LayerLink? layerLink;

  @override
  bool isRepaintBoundary = true;

  @override
  void debugAssertDoesMeetConstraints() {}

  @override
  Rect get paintBounds {
    return Rect.zero;
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    if (layerLink != null) {
      context.pushLayer(LeaderLayer(link: layerLink!), super.paint, offset);
    }
  }

  @override
  void performLayout() {}

  @override
  void performResize() {}

  @override
  Rect get semanticBounds => const Rect.fromLTWH(0.0, 0.0, 10.0, 20.0);
}

class TestThrowingRenderObject extends RenderObject {
  @override
  void performLayout() {
    throw FlutterError('TestThrowingRenderObject does not support performLayout.');
  }

  @override
  void debugAssertDoesMeetConstraints() {}

  @override
  Rect get paintBounds {
    assert(false); // The test shouldn't call this.
    return Rect.zero;
  }

  @override
  void performResize() {}

  @override
  Rect get semanticBounds {
    assert(false); // The test shouldn't call this.
    return Rect.zero;
  }
}

final class _TestPipelineOwner extends PipelineOwner {
  // Make these protected fields visible for testing.
  Iterable<RenderObject> get needLayout => super.nodesNeedingLayout;

  Iterable<RenderObject> get needPaint => super.nodesNeedingPaint;
}
