// 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 'package:flutter_test/flutter_test.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';

class TestMultiChildLayoutDelegate extends MultiChildLayoutDelegate {
  late BoxConstraints getSizeConstraints;

  @override
  Size getSize(BoxConstraints constraints) {
    if (!RenderObject.debugCheckingIntrinsics)
      getSizeConstraints = constraints;
    return const Size(200.0, 300.0);
  }

  Size? performLayoutSize;
  late Size performLayoutSize0;
  late Size performLayoutSize1;
  late bool performLayoutIsChild;

  @override
  void performLayout(Size size) {
    assert(!RenderObject.debugCheckingIntrinsics);
    expect(() {
      performLayoutSize = size;
      final BoxConstraints constraints = BoxConstraints.loose(size);
      performLayoutSize0 = layoutChild(0, constraints);
      performLayoutSize1 = layoutChild(1, constraints);
      performLayoutIsChild = hasChild('fred');
    }, returnsNormally);
  }

  bool shouldRelayoutCalled = false;
  bool shouldRelayoutValue = false;

  @override
  bool shouldRelayout(_) {
    assert(!RenderObject.debugCheckingIntrinsics);
    shouldRelayoutCalled = true;
    return shouldRelayoutValue;
  }
}

Widget buildFrame(MultiChildLayoutDelegate delegate) {
  return Center(
    child: CustomMultiChildLayout(
      children: <Widget>[
        LayoutId(id: 0, child: const SizedBox(width: 150.0, height: 100.0)),
        LayoutId(id: 1, child: const SizedBox(width: 100.0, height: 200.0)),
      ],
      delegate: delegate,
    ),
  );
}

class PreferredSizeDelegate extends MultiChildLayoutDelegate {
  PreferredSizeDelegate({ required this.preferredSize });

  final Size preferredSize;

  @override
  Size getSize(BoxConstraints constraints) => preferredSize;

  @override
  void performLayout(Size size) { }

  @override
  bool shouldRelayout(PreferredSizeDelegate oldDelegate) {
    return preferredSize != oldDelegate.preferredSize;
  }
}

class NotifierLayoutDelegate extends MultiChildLayoutDelegate {
  NotifierLayoutDelegate(this.size) : super(relayout: size);

  final ValueNotifier<Size> size;

  @override
  Size getSize(BoxConstraints constraints) => size.value;

  @override
  void performLayout(Size size) { }

  @override
  bool shouldRelayout(NotifierLayoutDelegate oldDelegate) {
    return size != oldDelegate.size;
  }
}

// LayoutDelegate that lays out child with id 0 and 1
// Used in the 'performLayout error control test' test case to trigger:
//  - error when laying out a non existent child and a child that has not been laid out
class ZeroAndOneIdLayoutDelegate extends MultiChildLayoutDelegate {
  @override
  void performLayout(Size size) {
    final BoxConstraints constraints = BoxConstraints.loose(size);
    layoutChild(0, constraints);
    layoutChild(1, constraints);
  }

  @override
  bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) => true;
}

// Used in the 'performLayout error control test' test case
//  to trigger an error when laying out child more than once
class DuplicateLayoutDelegate extends MultiChildLayoutDelegate {
  @override
  void performLayout(Size size) {
    final BoxConstraints constraints = BoxConstraints.loose(size);
    layoutChild(0, constraints);
    layoutChild(0, constraints);
  }

  @override
  bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) => true;
}
// Used in the 'performLayout error control test' test case
//  to trigger an error when positioning non existent child
class NonExistentPositionDelegate extends MultiChildLayoutDelegate {
  @override
  void performLayout(Size size) {
    positionChild(0, Offset.zero);
    positionChild(1, Offset.zero);
  }

  @override
  bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) => true;
}

// Used in the 'performLayout error control test' test case for triggering
//  to layout child more than once
class InvalidConstraintsChildLayoutDelegate extends MultiChildLayoutDelegate {
  @override
  void performLayout(Size size) {
    final BoxConstraints constraints = BoxConstraints.loose(
      // Invalid because width and height must be greater than or equal to 0
      const Size(-1, -1)
    );
    layoutChild(0, constraints);
  }

  @override
  bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) => true;
}

class LayoutWithMissingId extends ParentDataWidget<MultiChildLayoutParentData> {
  const LayoutWithMissingId({
    Key? key,
    required Widget child,
  }) : assert(child != null),
       super(key: key, child: child);

  @override
  void applyParentData(RenderObject renderObject) {}

  @override
  Type get debugTypicalAncestorWidgetClass => CustomMultiChildLayout;
}

void main() {
  testWidgets('Control test for CustomMultiChildLayout', (WidgetTester tester) async {
    final TestMultiChildLayoutDelegate delegate = TestMultiChildLayoutDelegate();
    await tester.pumpWidget(buildFrame(delegate));

    expect(delegate.getSizeConstraints.minWidth, 0.0);
    expect(delegate.getSizeConstraints.maxWidth, 800.0);
    expect(delegate.getSizeConstraints.minHeight, 0.0);
    expect(delegate.getSizeConstraints.maxHeight, 600.0);

    expect(delegate.performLayoutSize!.width, 200.0);
    expect(delegate.performLayoutSize!.height, 300.0);
    expect(delegate.performLayoutSize0.width, 150.0);
    expect(delegate.performLayoutSize0.height, 100.0);
    expect(delegate.performLayoutSize1.width, 100.0);
    expect(delegate.performLayoutSize1.height, 200.0);
    expect(delegate.performLayoutIsChild, false);
  });

  testWidgets('Test MultiChildDelegate shouldRelayout method', (WidgetTester tester) async {
    TestMultiChildLayoutDelegate delegate = TestMultiChildLayoutDelegate();
    await tester.pumpWidget(buildFrame(delegate));

    // Layout happened because the delegate was set.
    expect(delegate.performLayoutSize, isNotNull); // i.e. layout happened
    expect(delegate.shouldRelayoutCalled, isFalse);

    // Layout did not happen because shouldRelayout() returned false.
    delegate = TestMultiChildLayoutDelegate();
    delegate.shouldRelayoutValue = false;
    await tester.pumpWidget(buildFrame(delegate));
    expect(delegate.shouldRelayoutCalled, isTrue);
    expect(delegate.performLayoutSize, isNull);

    // Layout happened because shouldRelayout() returned true.
    delegate = TestMultiChildLayoutDelegate();
    delegate.shouldRelayoutValue = true;
    await tester.pumpWidget(buildFrame(delegate));
    expect(delegate.shouldRelayoutCalled, isTrue);
    expect(delegate.performLayoutSize, isNotNull);
  });

  testWidgets('Nested CustomMultiChildLayouts', (WidgetTester tester) async {
    final TestMultiChildLayoutDelegate delegate = TestMultiChildLayoutDelegate();
    await tester.pumpWidget(Center(
      child: CustomMultiChildLayout(
        children: <Widget>[
          LayoutId(
            id: 0,
            child: CustomMultiChildLayout(
              children: <Widget>[
                LayoutId(id: 0, child: const SizedBox(width: 150.0, height: 100.0)),
                LayoutId(id: 1, child: const SizedBox(width: 100.0, height: 200.0)),
              ],
              delegate: delegate,
            ),
          ),
          LayoutId(id: 1, child: const SizedBox(width: 100.0, height: 200.0)),
        ],
        delegate: delegate,
      ),
    ));

  });

  testWidgets('Loose constraints', (WidgetTester tester) async {
    final Key key = UniqueKey();
    await tester.pumpWidget(Center(
      child: CustomMultiChildLayout(
        key: key,
        delegate: PreferredSizeDelegate(preferredSize: const Size(300.0, 200.0)),
      ),
    ));

    final RenderBox box = tester.renderObject(find.byKey(key));
    expect(box.size.width, equals(300.0));
    expect(box.size.height, equals(200.0));

    await tester.pumpWidget(Center(
      child: CustomMultiChildLayout(
        key: key,
        delegate: PreferredSizeDelegate(preferredSize: const Size(350.0, 250.0)),
      ),
    ));

    expect(box.size.width, equals(350.0));
    expect(box.size.height, equals(250.0));
  });

  testWidgets('Can use listener for relayout', (WidgetTester tester) async {
    final ValueNotifier<Size> size = ValueNotifier<Size>(const Size(100.0, 200.0));

    await tester.pumpWidget(
      Center(
        child: CustomMultiChildLayout(
          delegate: NotifierLayoutDelegate(size),
        ),
      ),
    );

    RenderBox box = tester.renderObject(find.byType(CustomMultiChildLayout));
    expect(box.size, equals(const Size(100.0, 200.0)));

    size.value = const Size(150.0, 240.0);
    await tester.pump();

    box = tester.renderObject(find.byType(CustomMultiChildLayout));
    expect(box.size, equals(const Size(150.0, 240.0)));
  });

  group('performLayout error control test', () {
    Widget buildSingleChildFrame(MultiChildLayoutDelegate delegate) {
      return Center(
        child: CustomMultiChildLayout(
          children: <Widget>[LayoutId(id: 0, child: const SizedBox())],
          delegate: delegate,
        ),
      );
    }

    Future<void> expectFlutterErrorMessage({
      Widget? widget,
      MultiChildLayoutDelegate? delegate,
      required WidgetTester tester,
      required String message,
    }) async {
      final FlutterExceptionHandler? oldHandler = FlutterError.onError;
      final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
      FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
      try {
        await tester.pumpWidget(widget ?? buildSingleChildFrame(delegate!));
      } finally {
        FlutterError.onError = oldHandler;
      }
      expect(errors.length, isNonZero);
      expect(errors.first, isNotNull);
      expect(errors.first.exception, isFlutterError);
      expect((errors.first.exception as FlutterError).toStringDeep(), equalsIgnoringHashCodes(message));
    }

    testWidgets('layoutChild on non existent child', (WidgetTester tester) async {
      await expectFlutterErrorMessage(
        tester: tester,
        delegate: ZeroAndOneIdLayoutDelegate(),
        message:
          'FlutterError\n'
          '   The ZeroAndOneIdLayoutDelegate custom multichild layout delegate\n'
          '   tried to lay out a non-existent child.\n'
          '   There is no child with the id "1".\n'
      );
    });

    testWidgets('layoutChild more than once', (WidgetTester tester) async {
      await expectFlutterErrorMessage(
          tester: tester,
          delegate: DuplicateLayoutDelegate(),
          message:
            'FlutterError\n'
            '   The DuplicateLayoutDelegate custom multichild layout delegate\n'
            '   tried to lay out the child with id "0" more than once.\n'
            '   Each child must be laid out exactly once.\n'
      );
    });

    testWidgets('layoutChild on invalid size constraint', (WidgetTester tester) async {
      await expectFlutterErrorMessage(
        tester: tester,
        delegate: InvalidConstraintsChildLayoutDelegate(),
        message:
          'FlutterError\n'
          '   The InvalidConstraintsChildLayoutDelegate custom multichild\n'
          '   layout delegate provided invalid box constraints for the child\n'
          '   with id "0".\n'
          '   FlutterError\n'
          '   The minimum width and height must be greater than or equal to\n'
          '   zero.\n'
          '   The maximum width must be greater than or equal to the minimum\n'
          '   width.\n'
          '   The maximum height must be greater than or equal to the minimum\n'
          '   height.\n'
      );
    });

    testWidgets('positionChild on non existent child', (WidgetTester tester) async {
      await expectFlutterErrorMessage(
        tester: tester,
        delegate: NonExistentPositionDelegate(),
        message:
          'FlutterError\n'
          '   The NonExistentPositionDelegate custom multichild layout delegate\n'
          '   tried to position out a non-existent child:\n'
          '   There is no child with the id "1".\n'
      );
    });

    testWidgets("_callPerformLayout on child that doesn't have id", (WidgetTester tester) async {
      await expectFlutterErrorMessage(
        widget: Center(
          child: CustomMultiChildLayout(
            children: <Widget>[LayoutWithMissingId(child: Container(width: 100))],
            delegate: PreferredSizeDelegate(preferredSize: const Size(10, 10)),
          ),
        ),
        tester: tester,
        message:
          'FlutterError\n'
          '   Every child of a RenderCustomMultiChildLayoutBox must have an ID\n'
          '   in its parent data.\n'
          '   The following child has no ID: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT:\n'
          '     creator: ConstrainedBox ← Container ← LayoutWithMissingId ←\n'
          '       CustomMultiChildLayout ← Center ← [root]\n'
          '     parentData: offset=Offset(0.0, 0.0); id=null\n'
          '     constraints: MISSING\n'
          '     size: MISSING\n'
          '     additionalConstraints: BoxConstraints(w=100.0, 0.0<=h<=Infinity)\n'
      );
    });

    testWidgets('performLayout did not layout a child', (WidgetTester tester) async {
      await expectFlutterErrorMessage(
        widget: Center(
          child: CustomMultiChildLayout(
            children: <Widget>[
              LayoutId(id: 0, child: Container(width: 100)),
              LayoutId(id: 1, child: Container(width: 100)),
              LayoutId(id: 2, child: Container(width: 100)),
            ],
            delegate: ZeroAndOneIdLayoutDelegate(),
          ),
        ),
        tester: tester,
        message:
          'FlutterError\n'
          '   Each child must be laid out exactly once.\n'
          '   The ZeroAndOneIdLayoutDelegate custom multichild layout delegate'
          ' forgot to lay out the following child:\n'
          '     2: RenderConstrainedBox#62a34 NEEDS-LAYOUT NEEDS-PAINT\n'
      );
    });

    testWidgets('performLayout did not layout multiple child', (WidgetTester tester) async {
      await expectFlutterErrorMessage(
        widget: Center(
          child: CustomMultiChildLayout(
            children: <Widget>[
              LayoutId(id: 0, child: Container(width: 100)),
              LayoutId(id: 1, child: Container(width: 100)),
              LayoutId(id: 2, child: Container(width: 100)),
              LayoutId(id: 3, child: Container(width: 100)),
            ],
            delegate: ZeroAndOneIdLayoutDelegate(),
          ),
        ),
        tester: tester,
        message:
          'FlutterError\n'
          '   Each child must be laid out exactly once.\n'
          '   The ZeroAndOneIdLayoutDelegate custom multichild layout delegate'
          ' forgot to lay out the following children:\n'
          '     2: RenderConstrainedBox#62a34 NEEDS-LAYOUT NEEDS-PAINT\n'
          '     3: RenderConstrainedBox#62a34 NEEDS-LAYOUT NEEDS-PAINT\n'
      );
    });
  });
}
