// 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);
  finder.precache();
  final List<Rect> actual = <Rect>[];
  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(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(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(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(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(
        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(
        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',
    ));
  });
}
