// 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();
  });
}
