// 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_test/flutter_test.dart';

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

class TestState extends StatefulWidget {
  const TestState({ super.key, required this.child, required this.log });
  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()),
    )));
    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,
      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), warnIfMissed: false);
    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), warnIfMissed: false);
    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), 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), 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,
      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), 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,
      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), 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,
    )));
    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,
    )));
    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();
  });
}
