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

void main() {
  testWidgets('Can size according to aspect ratio', (WidgetTester tester) async {
    final Key outside = UniqueKey();
    final Key inside = UniqueKey();

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 200.0,
          child: FittedBox(
            key: outside,
            child: SizedBox(
              key: inside,
              width: 100.0,
              height: 50.0,
            ),
          ),
        ),
      ),
    );

    final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
    expect(outsideBox.size.width, 200.0);
    expect(outsideBox.size.height, 100.0);

    final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));
    expect(insideBox.size.width, 100.0);
    expect(insideBox.size.height, 50.0);

    final Offset insidePoint = insideBox.localToGlobal(const Offset(100.0, 50.0));
    final Offset outsidePoint = outsideBox.localToGlobal(const Offset(200.0, 100.0));

    expect(outsidePoint, equals(const Offset(500.0, 350.0)));
    expect(insidePoint, equals(outsidePoint));
  });

  testWidgets('Can contain child', (WidgetTester tester) async {
    final Key outside = UniqueKey();
    final Key inside = UniqueKey();

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 200.0,
          height: 200.0,
          child: FittedBox(
            key: outside,
            child: SizedBox(
              key: inside,
              width: 100.0,
              height: 50.0,
            ),
          ),
        ),
      ),
    );

    final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
    expect(outsideBox.size.width, 200.0);
    expect(outsideBox.size.height, 200.0);

    final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));
    expect(insideBox.size.width, 100.0);
    expect(insideBox.size.height, 50.0);

    final Offset insidePoint = insideBox.localToGlobal(const Offset(100.0, 0.0));
    final Offset outsidePoint = outsideBox.localToGlobal(const Offset(200.0, 50.0));

    expect(insidePoint, equals(outsidePoint));
  });

  testWidgets('Child can cover', (WidgetTester tester) async {
    final Key outside = UniqueKey();
    final Key inside = UniqueKey();

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 200.0,
          height: 200.0,
          child: FittedBox(
            key: outside,
            fit: BoxFit.cover,
            child: SizedBox(
              key: inside,
              width: 100.0,
              height: 50.0,
            ),
          ),
        ),
      ),
    );

    final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
    expect(outsideBox.size.width, 200.0);
    expect(outsideBox.size.height, 200.0);

    final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));
    expect(insideBox.size.width, 100.0);
    expect(insideBox.size.height, 50.0);

    final Offset insidePoint = insideBox.localToGlobal(const Offset(50.0, 25.0));
    final Offset outsidePoint = outsideBox.localToGlobal(const Offset(100.0, 100.0));

    expect(insidePoint, equals(outsidePoint));
  });

  testWidgets('FittedBox with no child', (WidgetTester tester) async {
    final Key key = UniqueKey();
    await tester.pumpWidget(
      Center(
        child: FittedBox(
          key: key,
          fit: BoxFit.cover,
        ),
      ),
    );

    final RenderBox box = tester.firstRenderObject(find.byKey(key));
    expect(box.size.width, 0.0);
    expect(box.size.height, 0.0);
  });

  testWidgets('Child can be aligned multiple ways in a row', (WidgetTester tester) async {
    final Key outside = UniqueKey();
    final Key inside = UniqueKey();

    { // align RTL

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.rtl,
          child: Center(
            child: SizedBox(
              width: 100.0,
              height: 100.0,
              child: FittedBox(
                key: outside,
                fit: BoxFit.scaleDown,
                alignment: AlignmentDirectional.bottomEnd,
                child: SizedBox(
                  key: inside,
                  width: 10.0,
                  height: 10.0,
                ),
              ),
            ),
          ),
        ),
      );

      final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
      expect(outsideBox.size.width, 100.0);
      expect(outsideBox.size.height, 100.0);

      final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));
      expect(insideBox.size.width, 10.0);
      expect(insideBox.size.height, 10.0);

      final Offset insideTopLeft = insideBox.localToGlobal(Offset.zero);
      final Offset outsideTopLeft = outsideBox.localToGlobal(const Offset(0.0, 90.0));
      final Offset insideBottomRight = insideBox.localToGlobal(const Offset(10.0, 10.0));
      final Offset outsideBottomRight = outsideBox.localToGlobal(const Offset(10.0, 100.0));

      expect(insideTopLeft, equals(outsideTopLeft));
      expect(insideBottomRight, equals(outsideBottomRight));
    }

    { // change direction

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Center(
            child: SizedBox(
              width: 100.0,
              height: 100.0,
              child: FittedBox(
                key: outside,
                fit: BoxFit.scaleDown,
                alignment: AlignmentDirectional.bottomEnd,
                child: SizedBox(
                  key: inside,
                  width: 10.0,
                  height: 10.0,
                ),
              ),
            ),
          ),
        ),
      );

      final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
      expect(outsideBox.size.width, 100.0);
      expect(outsideBox.size.height, 100.0);

      final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));
      expect(insideBox.size.width, 10.0);
      expect(insideBox.size.height, 10.0);

      final Offset insideTopLeft = insideBox.localToGlobal(Offset.zero);
      final Offset outsideTopLeft = outsideBox.localToGlobal(const Offset(90.0, 90.0));
      final Offset insideBottomRight = insideBox.localToGlobal(const Offset(10.0, 10.0));
      final Offset outsideBottomRight = outsideBox.localToGlobal(const Offset(100.0, 100.0));

      expect(insideTopLeft, equals(outsideTopLeft));
      expect(insideBottomRight, equals(outsideBottomRight));
    }

    { // change alignment

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Center(
            child: SizedBox(
              width: 100.0,
              height: 100.0,
              child: FittedBox(
                key: outside,
                fit: BoxFit.scaleDown,
                alignment: AlignmentDirectional.center,
                child: SizedBox(
                  key: inside,
                  width: 10.0,
                  height: 10.0,
                ),
              ),
            ),
          ),
        ),
      );

      final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
      expect(outsideBox.size.width, 100.0);
      expect(outsideBox.size.height, 100.0);

      final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));
      expect(insideBox.size.width, 10.0);
      expect(insideBox.size.height, 10.0);

      final Offset insideTopLeft = insideBox.localToGlobal(Offset.zero);
      final Offset outsideTopLeft = outsideBox.localToGlobal(const Offset(45.0, 45.0));
      final Offset insideBottomRight = insideBox.localToGlobal(const Offset(10.0, 10.0));
      final Offset outsideBottomRight = outsideBox.localToGlobal(const Offset(55.0, 55.0));

      expect(insideTopLeft, equals(outsideTopLeft));
      expect(insideBottomRight, equals(outsideBottomRight));
    }

    { // change size

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Center(
            child: SizedBox(
              width: 100.0,
              height: 100.0,
              child: FittedBox(
                key: outside,
                fit: BoxFit.scaleDown,
                alignment: AlignmentDirectional.center,
                child: SizedBox(
                  key: inside,
                  width: 30.0,
                  height: 10.0,
                ),
              ),
            ),
          ),
        ),
      );

      final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
      expect(outsideBox.size.width, 100.0);
      expect(outsideBox.size.height, 100.0);

      final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));
      expect(insideBox.size.width, 30.0);
      expect(insideBox.size.height, 10.0);

      final Offset insideTopLeft = insideBox.localToGlobal(Offset.zero);
      final Offset outsideTopLeft = outsideBox.localToGlobal(const Offset(35.0, 45.0));
      final Offset insideBottomRight = insideBox.localToGlobal(const Offset(30.0, 10.0));
      final Offset outsideBottomRight = outsideBox.localToGlobal(const Offset(65.0, 55.0));

      expect(insideTopLeft, equals(outsideTopLeft));
      expect(insideBottomRight, equals(outsideBottomRight));
    }

    { // change fit

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Center(
            child: SizedBox(
              width: 100.0,
              height: 100.0,
              child: FittedBox(
                key: outside,
                fit: BoxFit.fill,
                alignment: AlignmentDirectional.center,
                child: SizedBox(
                  key: inside,
                  width: 30.0,
                  height: 10.0,
                ),
              ),
            ),
          ),
        ),
      );

      final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
      expect(outsideBox.size.width, 100.0);
      expect(outsideBox.size.height, 100.0);

      final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));
      expect(insideBox.size.width, 30.0);
      expect(insideBox.size.height, 10.0);

      final Offset insideTopLeft = insideBox.localToGlobal(Offset.zero);
      final Offset outsideTopLeft = outsideBox.localToGlobal(Offset.zero);
      final Offset insideBottomRight = insideBox.localToGlobal(const Offset(30.0, 10.0));
      final Offset outsideBottomRight = outsideBox.localToGlobal(const Offset(100.0, 100.0));

      expect(insideTopLeft, equals(outsideTopLeft));
      expect(insideBottomRight, equals(outsideBottomRight));
    }
  });

  testWidgets('FittedBox layers - contain', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Center(
        child: SizedBox(
          width: 100.0,
          height: 10.0,
          child: FittedBox(
            child: SizedBox(
              width: 50.0,
              height: 50.0,
              child: RepaintBoundary(
                child: Placeholder(),
              ),
            ),
          ),
        ),
      ),
    );
    expect(getLayers(), <Type>[TransformLayer, TransformLayer, OffsetLayer]);
  });

  testWidgets('FittedBox layers - cover - horizontal', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Center(
        child: SizedBox(
          width: 100.0,
          height: 10.0,
          child: FittedBox(
            fit: BoxFit.cover,
            clipBehavior: Clip.hardEdge,
            child: SizedBox(
              width: 10.0,
              height: 50.0,
              child: RepaintBoundary(
                child: Placeholder(),
              ),
            ),
          ),
        ),
      ),
    );
    expect(getLayers(), <Type>[TransformLayer, ClipRectLayer, TransformLayer, OffsetLayer]);
  });

  testWidgets('FittedBox layers - cover - vertical', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Center(
        child: SizedBox(
          width: 10.0,
          height: 100.0,
          child: FittedBox(
            fit: BoxFit.cover,
            clipBehavior: Clip.hardEdge,
            child: SizedBox(
              width: 50.0,
              height: 10.0,
              child: RepaintBoundary(
                child: Placeholder(),
              ),
            ),
          ),
        ),
      ),
    );
    expect(getLayers(), <Type>[TransformLayer, ClipRectLayer, TransformLayer, OffsetLayer]);
  });

  testWidgets('FittedBox layers - none - clip', (WidgetTester tester) async {
    final List<double> values = <double>[10.0, 50.0, 100.0];
    for (final double a in values) {
      for (final double b in values) {
        for (final double c in values) {
          for (final double d in values) {
            await tester.pumpWidget(
              Center(
                child: SizedBox(
                  width: a,
                  height: b,
                  child: FittedBox(
                    fit: BoxFit.none,
                    clipBehavior: Clip.hardEdge,
                    child: SizedBox(
                      width: c,
                      height: d,
                      child: const RepaintBoundary(
                        child: Placeholder(),
                      ),
                    ),
                  ),
                ),
              ),
            );
            if (a < c || b < d) {
              expect(getLayers(), <Type>[TransformLayer, ClipRectLayer, OffsetLayer]);
            } else {
              expect(getLayers(), <Type>[TransformLayer, OffsetLayer]);
            }
          }
        }
      }
    }
  });

  testWidgets('Big child into small fitted box - hit testing', (WidgetTester tester) async {
    final GlobalKey key1 = GlobalKey();
    bool _pointerDown = false;
    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 100.0,
          height: 100.0,
          child: FittedBox(
            alignment: FractionalOffset.center,
            child: SizedBox(
              width: 1000.0,
              height: 1000.0,
              child: Listener(
                onPointerDown: (PointerDownEvent event) {
                  _pointerDown = true;
                },
                child: Container(
                  key: key1,
                  color: const Color(0xFF000000),
                ),
              ),
            ),
          ),
        ),
      ),
    );
    expect(_pointerDown, isFalse);
    await tester.tap(find.byKey(key1));
    expect(_pointerDown, isTrue);
  });

  testWidgets('Can set and update clipBehavior', (WidgetTester tester) async {
    await tester.pumpWidget(FittedBox(fit: BoxFit.none, child: Container()));
    final RenderFittedBox renderObject = tester.allRenderObjects.whereType<RenderFittedBox>().first;
    expect(renderObject.clipBehavior, equals(Clip.none));

    await tester.pumpWidget(FittedBox(fit: BoxFit.none, clipBehavior: Clip.antiAlias, child: Container()));
    expect(renderObject.clipBehavior, equals(Clip.antiAlias));
  });

  testWidgets('BoxFit.scaleDown matches size of child', (WidgetTester tester) async {
    final Key outside = UniqueKey();
    final Key inside = UniqueKey();

    // Does not scale up when child is smaller than constraints

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 200.0,
          child: FittedBox(
            key: outside,
            fit: BoxFit.scaleDown,
            child: SizedBox(
              key: inside,
              width: 100.0,
              height: 50.0,
            ),
          ),
        ),
      ),
    );

    final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
    final RenderBox insideBox = tester.firstRenderObject(find.byKey(inside));

    expect(outsideBox.size.width, 200.0);
    expect(outsideBox.size.height, 50.0);

    Offset outsidePoint = outsideBox.localToGlobal(Offset.zero);
    Offset insidePoint = insideBox.localToGlobal(Offset.zero);
    expect(insidePoint - outsidePoint, equals(const Offset(50.0, 0.0)));

    // Scales down when child is bigger than constraints

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 200.0,
          child: FittedBox(
            key: outside,
            fit: BoxFit.scaleDown,
            child: SizedBox(
              key: inside,
              width: 400.0,
              height: 200.0,
            ),
          ),
        ),
      ),
    );

    expect(outsideBox.size.width, 200.0);
    expect(outsideBox.size.height, 100.0);

    outsidePoint = outsideBox.localToGlobal(Offset.zero);
    insidePoint = insideBox.localToGlobal(Offset.zero);

    expect(insidePoint - outsidePoint, equals(Offset.zero));
  });

  testWidgets('Switching to and from BoxFit.scaleDown causes relayout', (WidgetTester tester) async {
    final Key outside = UniqueKey();

    final Widget scaleDownWidget = Center(
      child: SizedBox(
        width: 200.0,
        child: FittedBox(
          key: outside,
          fit: BoxFit.scaleDown,
          child: const SizedBox(
            width: 100.0,
            height: 50.0,
          ),
        ),
      ),
    );

    final Widget coverWidget = Center(
      child: SizedBox(
        width: 200.0,
        child: FittedBox(
          key: outside,
          child: const SizedBox(
            width: 100.0,
            height: 50.0,
          ),
        ),
      ),
    );

    await tester.pumpWidget(scaleDownWidget);

    final RenderBox outsideBox = tester.firstRenderObject(find.byKey(outside));
    expect(outsideBox.size.height, 50.0);

    await tester.pumpWidget(coverWidget);

    expect(outsideBox.size.height, 100.0);

    await tester.pumpWidget(scaleDownWidget);

    expect(outsideBox.size.height, 50.0);
  });

  testWidgets('FittedBox without child does not throw', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Center(
        child: SizedBox(
          width: 200.0,
          height: 200.0,
          child: FittedBox(),
        ),
      ),
    );

    expect(find.byType(FittedBox), findsOneWidget);

    // Tapping it also should not throw.
    await tester.tap(find.byType(FittedBox), warnIfMissed: false);
    expect(tester.takeException(), isNull);
  });
}

List<Type> getLayers() {
  final List<Type> layers = <Type>[];
  Layer? container = RendererBinding.instance!.renderView.debugLayer;
  while (container is ContainerLayer) {
    layers.add(container.runtimeType);
    expect(container.firstChild, same(container.lastChild));
    container = container.firstChild;
  }
  return layers;
}
