// 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/src/painting/basic_types.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.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.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(
                          mainAxis: Axis.vertical,
                          children: children,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      );
    } finally {
      FlutterError.onError = oldHandler;
    }
    expect(errors, isNotEmpty);
    expect(errors.first.exception, isFlutterError);
    expect(errors.first.exception.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'
    ));
  });
}
