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

import '../rendering/mock_canvas.dart';
import 'semantics_tester.dart';

class TestState extends StatefulWidget {
  const TestState({ Key? key, required this.child, required this.log }) : super(key: key);
  final Widget child;
  final List<String> log;
  @override
  State<TestState> createState() => _TestStateState();
}

class _TestStateState extends State<TestState> {
  @override
  void initState() {
    super.initState();
    widget.log.add('created new state');
  }
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

void main() {
  testWidgets('SliverVisibility', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final List<String> log = <String>[];
    const Key anchor = Key('drag');

    Widget _boilerPlate(Widget sliver) {
      return Localizations(
        locale: const Locale('en', 'us'),
        delegates: const <LocalizationsDelegate<dynamic>>[
          DefaultWidgetsLocalizations.delegate,
          DefaultMaterialLocalizations.delegate,
        ],
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: CustomScrollView(slivers: <Widget>[sliver])
          )
        )
      );
    }

    final Widget testChild = SliverToBoxAdapter(
      child: GestureDetector(
        onTap: () {
          log.add('tap');
        },
        child: Builder(
          builder: (BuildContext context) {
            final bool animating = TickerMode.of(context);
            return TestState(
              key: anchor,
              log: log,
              child: Text('a $animating', textDirection: TextDirection.rtl),
            );
          },
        ),
      )
    );

    // We now run a sequence of pumpWidget calls one after the other. In
    // addition to verifying that the right behavior is seen in each case, this
    // also verifies that the widget can dynamically change from state to state.

    // Default
    await tester.pumpWidget(_boilerPlate(SliverVisibility(sliver: testChild)));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paints..paragraph());
    RenderViewport renderViewport = tester.renderObject(find.byType(Viewport));
    RenderSliver renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>['created new state']);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['created new state', 'tap']);
    log.clear();

    // visible: false
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
    )));
    expect(find.byType(Text), findsNothing);
    expect(find.byType(Text, skipOffstage: false), findsNothing);
    expect(find.byType(SliverVisibility, skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 0.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(0));
    expect(log, <String>[]);
    expect(find.byKey(anchor), findsNothing);
    log.clear();

    // visible: false, with replacementSliver
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      replacementSliver: const SliverToBoxAdapter(child: Placeholder()),
      visible: false,
    )));
    expect(find.byType(Text, skipOffstage: false), findsNothing);
    expect(find.byType(Placeholder), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paints..path());
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 400.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(0));
    expect(log, <String>[]);
    expect(find.byKey(anchor), findsNothing);
    log.clear();

    // visible: true, with replacementSliver
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      replacementSliver: const SliverToBoxAdapter(child: Placeholder()),
      visible: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(Placeholder), findsNothing);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paints..paragraph());
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>['created new state']);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['created new state', 'tap']);
    log.clear();

    // visible: true, maintain all
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: true,
      maintainState: true,
      maintainAnimation: true,
      maintainSize: true,
      maintainInteractivity: true,
      maintainSemantics: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paints..paragraph());
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>['created new state']);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['created new state', 'tap']);
    log.clear();

    // visible: false, maintain all
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
      maintainState: true,
      maintainAnimation: true,
      maintainSize: true,
      maintainInteractivity: true,
      maintainSemantics: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>[]);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['tap']);
    log.clear();

    // visible: false, maintain all, replacementSliver
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      replacementSliver: const SliverToBoxAdapter(child: Placeholder()),
      visible: false,
      maintainState: true,
      maintainAnimation: true,
      maintainSize: true,
      maintainInteractivity: true,
      maintainSemantics: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(Placeholder), findsNothing);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>[]);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['tap']);
    log.clear();

    // visible: false, maintain all but semantics
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
      maintainState: true,
      maintainAnimation: true,
      maintainSize: true,
      maintainInteractivity: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(0));
    expect(log, <String>[]);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['tap']);
    log.clear();

    // visible: false, maintain all but interactivity
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
      maintainState: true,
      maintainAnimation: true,
      maintainSize: true,
      maintainSemantics: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>['created new state']);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['created new state']);
    log.clear();

    // visible: false, maintain state, animation, size.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
      maintainState: true,
      maintainAnimation: true,
      maintainSize: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(0));
    expect(log, <String>[]);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>[]);
    log.clear();

    // visible: false, maintain state and animation.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
      maintainState: true,
      maintainAnimation: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.byType(Text, skipOffstage: true), findsNothing);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 0.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(0));
    expect(log, <String>['created new state']);
    expect(find.byKey(anchor), findsNothing);
    log.clear();

    // visible: false, maintain state.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
      maintainState: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.byType(Text, skipOffstage: true), findsNothing);
    expect(find.text('a false', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 0.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(0));
    expect(log, <String>['created new state']);
    expect(find.byKey(anchor), findsNothing);
    log.clear();

    // Now we toggle the visibility off and on a few times to make sure that
    // works.

    // visible: true, maintain state
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: true,
      maintainState: true,
    )));
    expect(find.byType(Text), findsOneWidget);
    expect(find.text('a true'), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paints..paragraph());
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>[]);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['tap']);
    log.clear();

    // visible: false, maintain state.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
      maintainState: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.byType(Text, skipOffstage: true), findsNothing);
    expect(find.text('a false', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 0.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a false'), hasLength(0));
    expect(log, <String>[]);
    expect(find.byKey(anchor), findsNothing);
    log.clear();

    // visible: true, maintain state.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: true,
      maintainState: true,
    )));
    expect(find.byType(Text), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), findsOneWidget);
    expect(
      find.byType(SliverVisibility, skipOffstage: false), paints..paragraph());
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>[]);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['tap']);
    log.clear();

    // visible: false, maintain state.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
      maintainState: true,
    )));
    expect(find.byType(Text, skipOffstage: false), findsOneWidget);
    expect(find.byType(Text, skipOffstage: true), findsNothing);
    expect(find.text('a false', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 0.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a false'), hasLength(0));
    expect(log, <String>[]);
    expect(find.byKey(anchor), findsNothing);
    log.clear();

    // Same but without maintainState.

    // visible: false.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
    )));
    expect(find.byType(Text, skipOffstage: false), findsNothing);
    expect(find.byType(SliverVisibility, skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 0.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(0));
    expect(log, <String>[]);
    expect(find.byKey(anchor), findsNothing);
    log.clear();

    // visible: true.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: true,
    )));
    expect(find.byType(Text), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paints..paragraph());
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>['created new state']);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['created new state', 'tap']);
    log.clear();

    //visible: false.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: false,
    )));
    expect(find.byType(Text, skipOffstage: false), findsNothing);
    expect(find.byType(SliverVisibility, skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility, skipOffstage: false), paintsNothing);
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 0.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(0));
    expect(log, <String>[]);
    expect(find.byKey(anchor), findsNothing);
    log.clear();

    // visible: true.
    await tester.pumpWidget(_boilerPlate(SliverVisibility(
      sliver: testChild,
      visible: true,
    )));
    expect(find.byType(Text), findsOneWidget);
    expect(find.text('a true', skipOffstage: false), findsOneWidget);
    expect(find.byType(SliverVisibility), findsOneWidget);
    expect(find.byType(SliverVisibility), paints..paragraph());
    renderViewport = tester.renderObject(find.byType(Viewport));
    renderSliver = renderViewport.lastChild!;
    expect(renderSliver.geometry!.scrollExtent, 14.0);
    expect(renderSliver.constraints.crossAxisExtent, 800.0);
    expect(semantics.nodesWith(label: 'a true'), hasLength(1));
    expect(log, <String>['created new state']);
    await tester.tap(find.byKey(anchor));
    expect(log, <String>['created new state', 'tap']);
    log.clear();

    semantics.dispose();
  });
}
