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

final Matcher _matchesCommit = isMethodCall('TextInput.finishAutofillContext', arguments: true);
final Matcher _matchesCancel = isMethodCall('TextInput.finishAutofillContext', arguments: false);

void main() {
  testWidgets('AutofillGroup has the right clients', (WidgetTester tester) async {
    const Key outerKey = Key('outer');
    const Key innerKey = Key('inner');

    const TextField client1 = TextField(autofillHints: <String>['1']);
    const TextField client2 = TextField(autofillHints: <String>['2']);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: AutofillGroup(
            key: outerKey,
            child: Column(children: <Widget>[
              client1,
              AutofillGroup(
                key: innerKey,
                child: Column(children: const <Widget>[client2, TextField(autofillHints: null)]),
              ),
            ]),
          ),
        ),
      ),
    );

    final AutofillGroupState innerState = tester.state<AutofillGroupState>(find.byKey(innerKey));
    final AutofillGroupState outerState = tester.state<AutofillGroupState>(find.byKey(outerKey));

    final State<TextField> clientState1 = tester.state<State<TextField>>(find.byWidget(client1));
    final State<TextField> clientState2 = tester.state<State<TextField>>(find.byWidget(client2));

    expect(outerState.autofillClients.toList(), <State<TextField>>[clientState1]);
    // The second TextField in the AutofillGroup doesn't have autofill enabled.
    expect(innerState.autofillClients.toList(), <State<TextField>>[clientState2]);
  });

  testWidgets('new clients can be added & removed to a scope', (WidgetTester tester) async {
    const Key scopeKey = Key('scope');

    const TextField client1 = TextField(autofillHints: <String>['1']);
    TextField client2 = const TextField(autofillHints: null);

    late StateSetter setState;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: AutofillGroup(
            key: scopeKey,
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setter) {
                setState = setter;
                return Column(children: <Widget>[client1, client2]);
              },
            ),
          ),
        ),
      ),
    );

    final AutofillGroupState scopeState = tester.state<AutofillGroupState>(find.byKey(scopeKey));

    final State<TextField> clientState1 = tester.state<State<TextField>>(find.byWidget(client1));
    final State<TextField> clientState2 = tester.state<State<TextField>>(find.byWidget(client2));

    expect(scopeState.autofillClients.toList(), <State<TextField>>[clientState1]);

    // Add to scope.
    setState(() { client2 = const TextField(autofillHints: <String>['2']); });

    await tester.pump();

    expect(scopeState.autofillClients, contains(clientState1));
    expect(scopeState.autofillClients, contains(clientState2));
    expect(scopeState.autofillClients.length, 2);

    // Remove from scope again.
    setState(() { client2 = const TextField(autofillHints: null); });

    await tester.pump();

    expect(scopeState.autofillClients, <State<TextField>>[clientState1]);
  });

  testWidgets('AutofillGroup has the right clients after reparenting', (WidgetTester tester) async {
    const Key outerKey = Key('outer');
    const Key innerKey = Key('inner');
    final GlobalKey keyClient3 = GlobalKey();

    const TextField client1 = TextField(autofillHints: <String>['1']);
    const TextField client2 = TextField(autofillHints: <String>['2']);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: AutofillGroup(
            key: outerKey,
            child: Column(children: <Widget>[
              client1,
              AutofillGroup(
                key: innerKey,
                child: Column(children: <Widget>[
                  client2,
                  TextField(key: keyClient3, autofillHints: const <String>['3']),
                ]),
              ),
            ]),
          ),
        ),
      ),
    );

    final AutofillGroupState innerState = tester.state<AutofillGroupState>(find.byKey(innerKey));
    final AutofillGroupState outerState = tester.state<AutofillGroupState>(find.byKey(outerKey));

    final State<TextField> clientState1 = tester.state<State<TextField>>(find.byWidget(client1));
    final State<TextField> clientState2 = tester.state<State<TextField>>(find.byWidget(client2));
    final State<TextField> clientState3 = tester.state<State<TextField>>(find.byKey(keyClient3));

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: AutofillGroup(
            key: outerKey,
            child: Column(children: <Widget>[
              client1,
              TextField(key: keyClient3, autofillHints: const <String>['3']),
              AutofillGroup(
                key: innerKey,
                child: Column(children: const <Widget>[client2]),
              ),
            ]),
          ),
        ),
      ),
    );

    expect(outerState.autofillClients.length, 2);
    expect(outerState.autofillClients, contains(clientState1));
    expect(outerState.autofillClients, contains(clientState3));
    expect(innerState.autofillClients, <State<TextField>>[clientState2]);
  });

  testWidgets('disposing AutofillGroups', (WidgetTester tester) async {
    late StateSetter setState;
    const Key group1 = Key('group1');
    const Key group2 = Key('group2');
    const Key group3 = Key('group3');
    const TextField placeholder = TextField(autofillHints: <String>[AutofillHints.name]);

    List<Widget> children = const <Widget> [
      AutofillGroup(
        key: group1,
        child: AutofillGroup(child: placeholder),
      ),
      AutofillGroup(key: group2, onDisposeAction: AutofillContextAction.cancel, child: placeholder),
      AutofillGroup(
        key: group3,
        child: AutofillGroup(child: placeholder),
      ),
    ];

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: StatefulBuilder(
            builder: (BuildContext context, StateSetter setter) {
              setState = setter;
              return Column(children: children);
            },
          ),
        ),
      ),
    );

    expect(
      tester.testTextInput.log,
      isNot(contains(_matchesCommit)),
    );

    tester.testTextInput.log.clear();

    // Remove the first topmost group group1. Should commit.
    setState(() {
      children = const <Widget> [
        AutofillGroup(key: group2, onDisposeAction: AutofillContextAction.cancel, child: placeholder),
        AutofillGroup(
          key: group3,
          child: AutofillGroup(child: placeholder),
        ),
      ];
    });

    await tester.pump();

    expect(
      tester.testTextInput.log.single,
      _matchesCommit,
    );

    tester.testTextInput.log.clear();

    // Remove the topmost group group2. Should cancel.
    setState(() {
      children = const <Widget> [
        AutofillGroup(
          key: group3,
          child: AutofillGroup(child: placeholder),
        ),
      ];
    });

    await tester.pump();

    expect(
      tester.testTextInput.log.single,
      _matchesCancel,
    );

    tester.testTextInput.log.clear();

    // Remove the inner group within group3. No action.
    setState(() {
      children = const <Widget> [
        AutofillGroup(
          key: group3,
          child: placeholder,
        ),
      ];
    });

    await tester.pump();

    expect(
      tester.testTextInput.log,
      isNot(contains('TextInput.finishAutofillContext')),
    );

    tester.testTextInput.log.clear();

    // Remove the topmosts group group3. Should commit.
    setState(() {
      children = const <Widget> [];
    });

    await tester.pump();

    expect(
      tester.testTextInput.log.single,
      _matchesCommit,
    );
  });
}
