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

const List<Widget> children = <Widget>[
  SizedBox(width: 200.0, height: 150.0),
  SizedBox(width: 200.0, height: 150.0),
  SizedBox(width: 200.0, height: 150.0),
  SizedBox(width: 200.0, height: 150.0),
];

void expectRects(WidgetTester tester, List<Rect> expected) {
  final Finder finder = find.byType(SizedBox);
  final List<Rect> actual = <Rect>[];
  finder.runCached(() {
    for (int i = 0; i < expected.length; ++i) {
      final Finder current = finder.at(i);
      expect(current, findsOneWidget);
      actual.add(tester.getRect(finder.at(i)));
    }
  });
  expect(() => finder.at(expected.length), throwsRangeError);
  expect(actual, equals(expected));
}

void main() {

  testWidgets('ListBody down', (WidgetTester tester) async {
    await tester.pumpWidget(const Flex(
      direction: Axis.vertical,
      children: <Widget>[ ListBody(children: children) ],
    ));

    expectRects(
      tester,
      <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 150.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 300.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 450.0, 800.0, 150.0),
      ],
    );
  });

  testWidgets('ListBody up', (WidgetTester tester) async {
    await tester.pumpWidget(const Flex(
      direction: Axis.vertical,
      children: <Widget>[ ListBody(reverse: true, children: children) ],
    ));

    expectRects(
      tester,
      <Rect>[
        const Rect.fromLTWH(0.0, 450.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 300.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 150.0, 800.0, 150.0),
        const Rect.fromLTWH(0.0, 0.0, 800.0, 150.0),
      ],
    );
  });

  testWidgets('ListBody right', (WidgetTester tester) async {
    await tester.pumpWidget(const Flex(
      textDirection: TextDirection.ltr,
      direction: Axis.horizontal,
      children: <Widget>[
        Directionality(
          textDirection: TextDirection.ltr,
          child: ListBody(mainAxis: Axis.horizontal, children: children),
        ),
      ],
    ));

    expectRects(
      tester,
      <Rect>[
        const Rect.fromLTWH(0.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(200.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(400.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(600.0, 0.0, 200.0, 600.0),
      ],
    );
  });

  testWidgets('ListBody left', (WidgetTester tester) async {
    await tester.pumpWidget(const Flex(
      textDirection: TextDirection.ltr,
      direction: Axis.horizontal,
      children: <Widget>[
        Directionality(
          textDirection: TextDirection.rtl,
          child: ListBody(mainAxis: Axis.horizontal, children: children),
        ),
      ],
    ));

    expectRects(
      tester,
      <Rect>[
        const Rect.fromLTWH(600.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(400.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(200.0, 0.0, 200.0, 600.0),
        const Rect.fromLTWH(0.0, 0.0, 200.0, 600.0),
      ],
    );
  });

  testWidgets('Limited space along main axis error', (WidgetTester tester) async {
    final FlutterExceptionHandler oldHandler = FlutterError.onError!;
    final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
    FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
    try {
      await tester.pumpWidget(
        const SizedBox(
          width: 100,
          height: 100,
          child: Directionality(
            textDirection: TextDirection.rtl,
            child: ListBody(
              mainAxis: Axis.horizontal,
              children: children,
            ),
          ),
        ),
      );
    } finally {
      FlutterError.onError = oldHandler;
    }
    expect(errors, isNotEmpty);
    expect(errors.first.exception, isFlutterError);
    expect((errors.first.exception as FlutterError).toStringDeep(), equalsIgnoringHashCodes(
      'FlutterError\n'
      '   RenderListBody must have unlimited space along its main axis.\n'
      '   RenderListBody does not clip or resize its children, so it must\n'
      '   be placed in a parent that does not constrain the main axis.\n'
      '   You probably want to put the RenderListBody inside a\n'
      '   RenderViewport with a matching main axis.\n',
    ));
  });

  testWidgets('Nested ListBody unbounded cross axis error', (WidgetTester tester) async {
    final FlutterExceptionHandler oldHandler = FlutterError.onError!;
    final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
    FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
    try {
      await tester.pumpWidget(
        const Flex(
          textDirection: TextDirection.ltr,
          direction: Axis.horizontal,
          children: <Widget>[
            Directionality(
              textDirection: TextDirection.ltr,
              child: ListBody(
                mainAxis: Axis.horizontal,
                children: <Widget>[
                  Flex(
                    textDirection: TextDirection.ltr,
                    direction: Axis.vertical,
                    children: <Widget>[
                      Directionality(
                        textDirection: TextDirection.ltr,
                        child: ListBody(
                          children: children,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      );
    } finally {
      FlutterError.onError = oldHandler;
    }
    expect(errors, isNotEmpty);
    expect(errors.first.exception, isFlutterError);
    expect((errors.first.exception as FlutterError).toStringDeep(), equalsIgnoringHashCodes(
      'FlutterError\n'
      '   RenderListBody must have a bounded constraint for its cross axis.\n'
      '   RenderListBody forces its children to expand to fit the\n'
      "   RenderListBody's container, so it must be placed in a parent that\n"
      '   constrains the cross axis to a finite dimension.\n'
      '   If you are attempting to nest a RenderListBody with one direction\n'
      '   inside one of another direction, you will want to wrap the inner\n'
      '   one inside a box that fixes the dimension in that direction, for\n'
      '   example, a RenderIntrinsicWidth or RenderIntrinsicHeight object.\n'
      '   This is relatively expensive, however.\n',
    ));
  });
}
