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

@immutable
class Pair<T> {
  const Pair(this.first, this.second);
  final T? first;
  final T second;

  @override
  bool operator ==(Object other) {
    return other is Pair<T> && other.first == first && other.second == second;
  }

  @override
  int get hashCode => hashValues(first, second);

  @override
  String toString() => '($first,$second)';
}

/// Widget that will layout one child in the top half of this widget's size
/// and the other child in the bottom half. It will swap which child is on top
/// and which is on bottom every time the widget is rendered.
abstract class Swapper extends RenderObjectWidget {
  const Swapper({ this.stable, this.swapper });

  final Widget? stable;
  final Widget? swapper;

  @override
  SwapperElement createElement();

  @override
  RenderObject createRenderObject(BuildContext context) => RenderSwapper();
}

class SwapperWithProperOverrides extends Swapper {
  const SwapperWithProperOverrides({
    Widget? stable,
    Widget? swapper,
  }) : super(stable: stable, swapper: swapper);

  @override
  SwapperElement createElement() => SwapperElementWithProperOverrides(this);
}

class SwapperWithNoOverrides extends Swapper {
  const SwapperWithNoOverrides({
    Widget? stable,
    Widget? swapper,
  }) : super(stable: stable, swapper: swapper);

  @override
  SwapperElement createElement() => SwapperElementWithNoOverrides(this);
}

class SwapperWithDeprecatedOverrides extends Swapper {
  const SwapperWithDeprecatedOverrides({
    Widget? stable,
    Widget? swapper,
  }) : super(stable: stable, swapper: swapper);

  @override
  SwapperElement createElement() => SwapperElementWithDeprecatedOverrides(this);
}

abstract class SwapperElement extends RenderObjectElement {
  SwapperElement(Swapper widget) : super(widget);

  Element? stable;
  Element? swapper;
  bool swapperIsOnTop = true;
  List<dynamic> insertSlots = <dynamic>[];
  List<Pair<dynamic>> moveSlots = <Pair<dynamic>>[];
  List<dynamic> removeSlots = <dynamic>[];

  @override
  Swapper get widget => super.widget as Swapper;

  @override
  RenderSwapper get renderObject => super.renderObject as RenderSwapper;

  @override
  void visitChildren(ElementVisitor visitor) {
    if (stable != null)
      visitor(stable!);
    if (swapper != null)
      visitor(swapper!);
  }

  @override
  void update(Swapper newWidget) {
    super.update(newWidget);
    _updateChildren(newWidget);
  }

  @override
  void mount(Element? parent, dynamic newSlot) {
    super.mount(parent, newSlot);
    _updateChildren(widget);
  }

  void _updateChildren(Swapper widget) {
    stable = updateChild(stable, widget.stable, 'stable');
    swapper = updateChild(swapper, widget.swapper, swapperIsOnTop);
    swapperIsOnTop = !swapperIsOnTop;
  }
}

class SwapperElementWithProperOverrides extends SwapperElement {
  SwapperElementWithProperOverrides(Swapper widget) : super(widget);

  @override
  void insertRenderObjectChild(RenderBox child, dynamic slot) {
    insertSlots.add(slot);
    assert(child != null);
    if (slot == 'stable')
      renderObject.stable = child;
    else
      renderObject.setSwapper(child, slot as bool);
  }

  @override
  void moveRenderObjectChild(RenderBox child, bool oldIsOnTop, bool newIsOnTop) {
    moveSlots.add(Pair<bool>(oldIsOnTop, newIsOnTop));
    assert(oldIsOnTop == !newIsOnTop);
    renderObject.setSwapper(child, newIsOnTop);
  }

  @override
  void removeRenderObjectChild(RenderBox child, dynamic slot) {
    removeSlots.add(slot);
    if (slot == 'stable')
      renderObject.stable = null;
    else
      renderObject.setSwapper(null, slot as bool);
  }
}

class SwapperElementWithNoOverrides extends SwapperElement {
  SwapperElementWithNoOverrides(Swapper widget) : super(widget);
}

class SwapperElementWithDeprecatedOverrides extends SwapperElement {
  SwapperElementWithDeprecatedOverrides(Swapper widget) : super(widget);

  @override
  // ignore: must_call_super
  void insertChildRenderObject(RenderBox child, dynamic slot) {
    insertSlots.add(slot);
    assert(child != null);
    if (slot == 'stable')
      renderObject.stable = child;
    else
      renderObject.setSwapper(child, slot as bool);
  }

  @override
  // ignore: must_call_super
  void moveChildRenderObject(RenderBox child, bool isOnTop) {
    moveSlots.add(Pair<bool>(null, isOnTop));
    renderObject.setSwapper(child, isOnTop);
  }

  @override
  // ignore: must_call_super
  void removeChildRenderObject(RenderBox child) {
    removeSlots.add(null);
    if (child == renderObject._stable)
      renderObject.stable = null;
    else
      renderObject.setSwapper(null, swapperIsOnTop);
  }
}

class RenderSwapper extends RenderBox {
  RenderBox? _stable;
  RenderBox? get stable => _stable;
  set stable(RenderBox? child) {
    if (child == _stable)
      return;
    if (_stable != null)
      dropChild(_stable!);
    _stable = child;
    if (child != null)
      adoptChild(child);
  }

  bool? _swapperIsOnTop;
  RenderBox? _swapper;
  RenderBox? get swapper => _swapper;
  void setSwapper(RenderBox? child, bool isOnTop) {
    if (isOnTop != _swapperIsOnTop) {
      _swapperIsOnTop = isOnTop;
      markNeedsLayout();
    }
    if (child == _swapper)
      return;
    if (_swapper != null)
      dropChild(_swapper!);
    _swapper = child;
    if (child != null)
      adoptChild(child);
  }

  @override
  void visitChildren(RenderObjectVisitor visitor) {
    if (_stable != null)
      visitor(_stable!);
    if (_swapper != null)
      visitor(_swapper!);
  }

  @override
  void attach(PipelineOwner owner) {
    super.attach(owner);
    visitChildren((RenderObject child) => child.attach(owner));
  }

  @override
  void detach() {
    super.detach();
    visitChildren((RenderObject child) => child.detach());
  }

  @override
  void performLayout() {
    assert(constraints.hasBoundedWidth);
    assert(constraints.hasTightHeight);
    size = constraints.biggest;
    const Offset topOffset = Offset.zero;
    final Offset bottomOffset = Offset(0, size.height / 2);
    final BoxConstraints childConstraints = constraints.copyWith(
      minHeight: constraints.minHeight / 2,
      maxHeight: constraints.maxHeight / 2,
    );
    if (_stable != null) {
      final BoxParentData stableParentData = _stable!.parentData! as BoxParentData;
      _stable!.layout(childConstraints);
      stableParentData.offset = _swapperIsOnTop! ? bottomOffset : topOffset;
    }
    if (_swapper != null) {
      final BoxParentData swapperParentData = _swapper!.parentData! as BoxParentData;
      _swapper!.layout(childConstraints);
      swapperParentData.offset = _swapperIsOnTop! ? topOffset : bottomOffset;
    }
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    visitChildren((RenderObject child) {
      final BoxParentData childParentData = child.parentData! as BoxParentData;
      context.paintChild(child, offset + childParentData.offset);
    });
  }

  @override
  void redepthChildren() {
    visitChildren((RenderObject child) => redepthChild(child));
  }
}

BoxParentData parentDataFor(RenderObject renderObject) => renderObject.parentData! as BoxParentData;

void main() {
  testWidgets('RenderObjectElement *RenderObjectChild methods get called with correct arguments', (WidgetTester tester) async {
    const Key redKey = ValueKey<String>('red');
    const Key blueKey = ValueKey<String>('blue');
    Widget widget() {
      return SwapperWithProperOverrides(
        stable: ColoredBox(
          key: redKey,
          color: Color(nonconst(0xffff0000)),
        ),
        swapper: ColoredBox(
          key: blueKey,
          color: Color(nonconst(0xff0000ff)),
        ),
      );
    }

    await tester.pumpWidget(widget());
    final SwapperElement swapper = tester.element<SwapperElement>(find.byType(SwapperWithProperOverrides));
    final RenderBox redBox = tester.renderObject<RenderBox>(find.byKey(redKey));
    final RenderBox blueBox = tester.renderObject<RenderBox>(find.byKey(blueKey));
    expect(swapper.insertSlots.length, 2);
    expect(swapper.insertSlots, contains('stable'));
    expect(swapper.insertSlots, contains(true));
    expect(swapper.moveSlots, isEmpty);
    expect(swapper.removeSlots, isEmpty);
    expect(parentDataFor(redBox).offset, const Offset(0, 300));
    expect(parentDataFor(blueBox).offset, Offset.zero);
    await tester.pumpWidget(widget());
    expect(swapper.insertSlots.length, 2);
    expect(swapper.moveSlots.length, 1);
    expect(swapper.moveSlots, contains(const Pair<bool>(true, false)));
    expect(swapper.removeSlots, isEmpty);
    expect(parentDataFor(redBox).offset, Offset.zero);
    expect(parentDataFor(blueBox).offset, const Offset(0, 300));
    await tester.pumpWidget(const SwapperWithProperOverrides());
    expect(redBox.attached, false);
    expect(blueBox.attached, false);
    expect(swapper.insertSlots.length, 2);
    expect(swapper.moveSlots.length, 1);
    expect(swapper.removeSlots.length, 2);
    expect(swapper.removeSlots, contains('stable'));
    expect(swapper.removeSlots, contains(false));
  });

  testWidgets('RenderObjectElement *RenderObjectChild methods delegate to deprecated methods', (WidgetTester tester) async {
    const Key redKey = ValueKey<String>('red');
    const Key blueKey = ValueKey<String>('blue');
    Widget widget() {
      return SwapperWithDeprecatedOverrides(
        stable: ColoredBox(
          key: redKey,
          color: Color(nonconst(0xffff0000)),
        ),
        swapper: ColoredBox(
          key: blueKey,
          color: Color(nonconst(0xff0000ff)),
        ),
      );
    }

    await tester.pumpWidget(widget());
    final SwapperElement swapper = tester.element<SwapperElement>(find.byType(SwapperWithDeprecatedOverrides));
    final RenderBox redBox = tester.renderObject<RenderBox>(find.byKey(redKey));
    final RenderBox blueBox = tester.renderObject<RenderBox>(find.byKey(blueKey));
    expect(swapper.insertSlots.length, 2);
    expect(swapper.insertSlots, contains('stable'));
    expect(swapper.insertSlots, contains(true));
    expect(swapper.moveSlots, isEmpty);
    expect(swapper.removeSlots, isEmpty);
    expect(parentDataFor(redBox).offset, const Offset(0, 300));
    expect(parentDataFor(blueBox).offset, Offset.zero);
    await tester.pumpWidget(widget());
    expect(swapper.insertSlots.length, 2);
    expect(swapper.moveSlots.length, 1);
    expect(swapper.moveSlots, contains(const Pair<bool>(null, false)));
    expect(swapper.removeSlots, isEmpty);
    expect(parentDataFor(redBox).offset, Offset.zero);
    expect(parentDataFor(blueBox).offset, const Offset(0, 300));
    await tester.pumpWidget(const SwapperWithDeprecatedOverrides());
    expect(redBox.attached, false);
    expect(blueBox.attached, false);
    expect(swapper.insertSlots.length, 2);
    expect(swapper.moveSlots.length, 1);
    expect(swapper.removeSlots.length, 2);
    expect(swapper.removeSlots, <bool?>[null,null]);
  });

  testWidgets('RenderObjectElement *ChildRenderObject methods fail with deprecation message', (WidgetTester tester) async {
    const Key redKey = ValueKey<String>('red');
    const Key blueKey = ValueKey<String>('blue');
    Widget widget() {
      return SwapperWithNoOverrides(
        stable: ColoredBox(
          key: redKey,
          color: Color(nonconst(0xffff0000)),
        ),
        swapper: ColoredBox(
          key: blueKey,
          color: Color(nonconst(0xff0000ff)),
        ),
      );
    }

    await tester.pumpWidget(widget());
    final FlutterError error = tester.takeException() as FlutterError;
    final ErrorSummary summary = error.diagnostics.first as ErrorSummary;
    expect(summary.toString(), contains('deprecated'));
  });
}
