// 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/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.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(
      delegate: delegate,
      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)),
      ],
    ),
  );
}

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(
        delegate: delegate,
        children: <Widget>[
          LayoutId(
            id: 0,
            child: CustomMultiChildLayout(
              delegate: delegate,
              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)),
              ],
            ),
          ),
          LayoutId(id: 1, child: const SizedBox(width: 100.0, height: 200.0)),
        ],
      ),
    ));

  });

  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(
          delegate: delegate,
          children: <Widget>[LayoutId(id: 0, child: const SizedBox())],
        ),
      );
    }

    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(
            delegate: PreferredSizeDelegate(preferredSize: const Size(10, 10)),
            children: <Widget>[LayoutWithMissingId(child: Container(width: 100))],
          ),
        ),
        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(
            delegate: ZeroAndOneIdLayoutDelegate(),
            children: <Widget>[
              LayoutId(id: 0, child: Container(width: 100)),
              LayoutId(id: 1, child: Container(width: 100)),
              LayoutId(id: 2, child: Container(width: 100)),
            ],
          ),
        ),
        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(
            delegate: ZeroAndOneIdLayoutDelegate(),
            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)),
            ],
          ),
        ),
        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',
      );
    });
  });
}
