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

// A simple "flat" InheritedModel: the data model is just 3 integer
// valued fields: a, b, c.
class ABCModel extends InheritedModel<String> {
  const ABCModel({
    Key? key,
    this.a,
    this.b,
    this.c,
    this.aspects,
    required Widget child,
  }) : super(key: key, child: child);

  final int? a;
  final int? b;
  final int? c;

  // The aspects (fields) of this model that widgets can depend on with
  // inheritFrom.
  //
  // This property is null by default, which means that the model supports
  // all 3 fields.
  final Set<String>? aspects;

  @override
  bool isSupportedAspect(Object aspect) {
    return aspect == null || aspects == null || aspects!.contains(aspect);
  }

  @override
  bool updateShouldNotify(ABCModel old) {
    return !setEquals<String>(aspects, old.aspects) || a != old.a || b != old.b || c != old.c;
  }

  @override
  bool updateShouldNotifyDependent(ABCModel old, Set<String> dependencies) {
    return !setEquals<String>(aspects, old.aspects)
        || (a != old.a && dependencies.contains('a'))
        || (b != old.b && dependencies.contains('b'))
        || (c != old.c && dependencies.contains('c'));
  }

  static ABCModel? of(BuildContext context, { String? fieldName }) {
    return InheritedModel.inheritFrom<ABCModel>(context, aspect: fieldName);
  }
}

class ShowABCField extends StatefulWidget {
  const ShowABCField({ Key? key, required this.fieldName }) : super(key: key);

  final String fieldName;

  @override
  State<ShowABCField> createState() => _ShowABCFieldState();
}

class _ShowABCFieldState extends State<ShowABCField> {
  int _buildCount = 0;

  @override
  Widget build(BuildContext context) {
    final ABCModel abc = ABCModel.of(context, fieldName: widget.fieldName)!;
    final int? value = widget.fieldName == 'a' ? abc.a : (widget.fieldName == 'b' ? abc.b : abc.c);
    return Text('${widget.fieldName}: $value [${_buildCount++}]');
  }
}

void main() {
  testWidgets('InheritedModel basics', (WidgetTester tester) async {
    int _a = 0;
    int _b = 1;
    int _c = 2;

    final Widget abcPage = StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        const Widget showA = ShowABCField(fieldName: 'a');
        const Widget showB = ShowABCField(fieldName: 'b');
        const Widget showC = ShowABCField(fieldName: 'c');

        // Unconditionally depends on the ABCModel: rebuilt when any
        // aspect of the model changes.
        final Widget showABC = Builder(
          builder: (BuildContext context) {
            final ABCModel abc = ABCModel.of(context)!;
            return Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}');
          },
        );

        return Scaffold(
          body: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return ABCModel(
                a: _a,
                b: _b,
                c: _c,
                child: Center(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      showA,
                      showB,
                      showC,
                      showABC,
                      ElevatedButton(
                        child: const Text('Increment a'),
                        onPressed: () {
                          // Rebuilds the ABCModel which triggers a rebuild
                          // of showA because showA depends on the 'a' aspect
                          // of the ABCModel.
                          setState(() { _a += 1; });
                        },
                      ),
                      ElevatedButton(
                        child: const Text('Increment b'),
                        onPressed: () {
                          // Rebuilds the ABCModel which triggers a rebuild
                          // of showB because showB depends on the 'b' aspect
                          // of the ABCModel.
                          setState(() { _b += 1; });
                        },
                      ),
                      ElevatedButton(
                        child: const Text('Increment c'),
                        onPressed: () {
                          // Rebuilds the ABCModel which triggers a rebuild
                          // of showC because showC depends on the 'c' aspect
                          // of the ABCModel.
                          setState(() { _c += 1; });
                        },
                      ),
                    ],
                  ),
                ),
              );
            },
          ),
        );
      },
    );

    await tester.pumpWidget(MaterialApp(home: abcPage));

    expect(find.text('a: 0 [0]'), findsOneWidget);
    expect(find.text('b: 1 [0]'), findsOneWidget);
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 0 b: 1 c: 2'), findsOneWidget);

    await tester.tap(find.text('Increment a'));
    await tester.pumpAndSettle();
    // Verify that field 'a' was incremented, but only the showA
    // and showABC widgets were rebuilt.
    expect(find.text('a: 1 [1]'), findsOneWidget);
    expect(find.text('b: 1 [0]'), findsOneWidget);
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 1 b: 1 c: 2'), findsOneWidget);

    // Verify that field 'a' was incremented, but only the showA
    // and showABC widgets were rebuilt.
    await tester.tap(find.text('Increment a'));
    await tester.pumpAndSettle();
    expect(find.text('a: 2 [2]'), findsOneWidget);
    expect(find.text('b: 1 [0]'), findsOneWidget);
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 2 b: 1 c: 2'), findsOneWidget);

    // Verify that field 'b' was incremented, but only the showB
    // and showABC widgets were rebuilt.
    await tester.tap(find.text('Increment b'));
    await tester.pumpAndSettle();
    expect(find.text('a: 2 [2]'), findsOneWidget);
    expect(find.text('b: 2 [1]'), findsOneWidget);
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 2 b: 2 c: 2'), findsOneWidget);

    // Verify that field 'c' was incremented, but only the showC
    // and showABC widgets were rebuilt.
    await tester.tap(find.text('Increment c'));
    await tester.pumpAndSettle();
    expect(find.text('a: 2 [2]'), findsOneWidget);
    expect(find.text('b: 2 [1]'), findsOneWidget);
    expect(find.text('c: 3 [1]'), findsOneWidget);
    expect(find.text('a: 2 b: 2 c: 3'), findsOneWidget);
  });

  testWidgets('Looking up an non existent InheritedModel ancestor returns null', (WidgetTester tester) async {
    ABCModel? inheritedModel;

    await tester.pumpWidget(
      Builder(
        builder: (BuildContext context) {
          inheritedModel = InheritedModel.inheritFrom(context);
          return Container();
        },
      ),
    );
    // Shouldn't crash first of all.

    expect(inheritedModel, null);
  });

  testWidgets('Inner InheritedModel shadows the outer one', (WidgetTester tester) async {
    int _a = 0;
    int _b = 1;
    int _c = 2;

    // Same as in abcPage in the "InheritedModel basics" test except:
    // there are two ABCModels and the inner model's "a" and "b"
    // properties shadow (override) the outer model. Further complicating
    // matters: the inner model only supports the model's "a" aspect,
    // so showB and showC will depend on the outer model.
    final Widget abcPage = StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        const Widget showA = ShowABCField(fieldName: 'a');
        const Widget showB = ShowABCField(fieldName: 'b');
        const Widget showC = ShowABCField(fieldName: 'c');

        // Unconditionally depends on the closest ABCModel ancestor.
        // Which is the inner model, for which b,c are null.
        final Widget showABC = Builder(
          builder: (BuildContext context) {
            final ABCModel abc = ABCModel.of(context)!;
            return Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context).textTheme.headline6);
          },
        );

        return Scaffold(
          body: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return ABCModel( // The "outer" model
                a: _a,
                b: _b,
                c: _c,
                child: ABCModel( // The "inner" model
                  a: 100 + _a,
                  b: 100 + _b,
                  aspects: const <String>{'a'},
                  child: Center(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        showA,
                        showB,
                        showC,
                        const SizedBox(height: 24.0),
                        showABC,
                        const SizedBox(height: 24.0),
                        ElevatedButton(
                          child: const Text('Increment a'),
                          onPressed: () {
                            setState(() { _a += 1; });
                          },
                        ),
                        ElevatedButton(
                          child: const Text('Increment b'),
                          onPressed: () {
                            setState(() { _b += 1; });
                          },
                        ),
                        ElevatedButton(
                          child: const Text('Increment c'),
                          onPressed: () {
                            setState(() { _c += 1; });
                          },
                        ),
                      ],
                    ),
                  ),
                ),
              );
            },
          ),
        );
      },
    );

    await tester.pumpWidget(MaterialApp(home: abcPage));
    expect(find.text('a: 100 [0]'), findsOneWidget);
    expect(find.text('b: 1 [0]'), findsOneWidget);
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 100 b: 101 c: null'), findsOneWidget);

    await tester.tap(find.text('Increment a'));
    await tester.pumpAndSettle();
    // Verify that field 'a' was incremented, but only the showA
    // and showABC widgets were rebuilt.
    expect(find.text('a: 101 [1]'), findsOneWidget);
    expect(find.text('b: 1 [0]'), findsOneWidget);
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 101 b: 101 c: null'), findsOneWidget);

    await tester.tap(find.text('Increment a'));
    await tester.pumpAndSettle();
    // Verify that field 'a' was incremented, but only the showA
    // and showABC widgets were rebuilt.
    expect(find.text('a: 102 [2]'), findsOneWidget);
    expect(find.text('b: 1 [0]'), findsOneWidget);
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 102 b: 101 c: null'), findsOneWidget);

    // Verify that field 'b' was incremented, but only the showB
    // and showABC widgets were rebuilt.
    await tester.tap(find.text('Increment b'));
    await tester.pumpAndSettle();
    expect(find.text('a: 102 [2]'), findsOneWidget);
    expect(find.text('b: 2 [1]'), findsOneWidget);
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 102 b: 102 c: null'), findsOneWidget);

    // Verify that field 'c' was incremented, but only the showC
    // and showABC widgets were rebuilt.
    await tester.tap(find.text('Increment c'));
    await tester.pumpAndSettle();
    expect(find.text('a: 102 [2]'), findsOneWidget);
    expect(find.text('b: 2 [1]'), findsOneWidget);
    expect(find.text('c: 3 [1]'), findsOneWidget);
    expect(find.text('a: 102 b: 102 c: null'), findsOneWidget);
  });

  testWidgets('InheritedModel inner models supported aspect change', (WidgetTester tester) async {
    int _a = 0;
    int _b = 1;
    int _c = 2;
    Set<String>? _innerModelAspects = <String>{'a'};

    // Same as in abcPage in the "Inner InheritedModel shadows the outer one"
    // test except: the "Add b aspect" changes adds 'b' to the set of
    // aspects supported by the inner model.
    final Widget abcPage = StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        const Widget showA = ShowABCField(fieldName: 'a');
        const Widget showB = ShowABCField(fieldName: 'b');
        const Widget showC = ShowABCField(fieldName: 'c');

        // Unconditionally depends on the closest ABCModel ancestor.
        // Which is the inner model, for which b,c are null.
        final Widget showABC = Builder(
          builder: (BuildContext context) {
            final ABCModel abc = ABCModel.of(context)!;
            return Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context).textTheme.headline6);
          },
        );

        return Scaffold(
          body: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return ABCModel( // The "outer" model
                a: _a,
                b: _b,
                c: _c,
                child: ABCModel( // The "inner" model
                  a: 100 + _a,
                  b: 100 + _b,
                  aspects: _innerModelAspects,
                  child: Center(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        showA,
                        showB,
                        showC,
                        const SizedBox(height: 24.0),
                        showABC,
                        const SizedBox(height: 24.0),
                        ElevatedButton(
                          child: const Text('Increment a'),
                          onPressed: () {
                            setState(() { _a += 1; });
                          },
                        ),
                        ElevatedButton(
                          child: const Text('Increment b'),
                          onPressed: () {
                            setState(() { _b += 1; });
                          },
                        ),
                        ElevatedButton(
                          child: const Text('Increment c'),
                          onPressed: () {
                            setState(() { _c += 1; });
                          },
                        ),
                        ElevatedButton(
                          child: const Text('rebuild'),
                          onPressed: () {
                            setState(() {
                              // Rebuild both models
                            });
                          },
                        ),
                      ],
                    ),
                  ),
                ),
              );
            },
          ),
        );
      },
    );

    _innerModelAspects = <String>{'a'};
    await tester.pumpWidget(MaterialApp(home: abcPage));
    expect(find.text('a: 100 [0]'), findsOneWidget); // showA depends on the inner model
    expect(find.text('b: 1 [0]'), findsOneWidget); // showB depends on the outer model
    expect(find.text('c: 2 [0]'), findsOneWidget);
    expect(find.text('a: 100 b: 101 c: null'), findsOneWidget); // inner model's a, b, c

    _innerModelAspects = <String>{'a', 'b'};
    await tester.tap(find.text('rebuild'));
    await tester.pumpAndSettle();
    expect(find.text('a: 100 [1]'), findsOneWidget); // rebuilt showA still depend on the inner model
    expect(find.text('b: 101 [1]'), findsOneWidget); // rebuilt showB now depends on the inner model
    expect(find.text('c: 2 [1]'), findsOneWidget); // rebuilt showC still depends on the outer model
    expect(find.text('a: 100 b: 101 c: null'), findsOneWidget); // inner model's a, b, c

    // Verify that field 'a' was incremented, but only the showA
    // and showABC widgets were rebuilt.
    await tester.tap(find.text('Increment a'));
    await tester.pumpAndSettle();
    expect(find.text('a: 101 [2]'), findsOneWidget); // rebuilt showA still depends on the inner model
    expect(find.text('b: 101 [1]'), findsOneWidget);
    expect(find.text('c: 2 [1]'), findsOneWidget);
    expect(find.text('a: 101 b: 101 c: null'), findsOneWidget);

    // Verify that field 'b' was incremented, but only the showB
    // and showABC widgets were rebuilt.
    await tester.tap(find.text('Increment b'));
    await tester.pumpAndSettle();
    expect(find.text('a: 101 [2]'), findsOneWidget); // rebuilt showB still depends on the inner model
    expect(find.text('b: 102 [2]'), findsOneWidget);
    expect(find.text('c: 2 [1]'), findsOneWidget);
    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget);

    // Verify that field 'c' was incremented, but only the showC
    // and showABC widgets were rebuilt.
    await tester.tap(find.text('Increment c'));
    await tester.pumpAndSettle();
    expect(find.text('a: 101 [2]'), findsOneWidget);
    expect(find.text('b: 102 [2]'), findsOneWidget);
    expect(find.text('c: 3 [2]'), findsOneWidget); // rebuilt showC still depends on the outer model
    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget);

    _innerModelAspects = <String>{'a', 'b', 'c'};
    await tester.tap(find.text('rebuild'));
    await tester.pumpAndSettle();
    expect(find.text('a: 101 [3]'), findsOneWidget); // rebuilt showA still depend on the inner model
    expect(find.text('b: 102 [3]'), findsOneWidget); // rebuilt showB still depends on the inner model
    expect(find.text('c: null [3]'), findsOneWidget); // rebuilt showC now depends on the inner model
    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget); // inner model's a, b, c

    // Now the inner model supports no aspects
    _innerModelAspects = <String>{};
    await tester.tap(find.text('rebuild'));
    await tester.pumpAndSettle();
    expect(find.text('a: 1 [4]'), findsOneWidget); // rebuilt showA now depends on the outer model
    expect(find.text('b: 2 [4]'), findsOneWidget); // rebuilt showB now depends on the outer model
    expect(find.text('c: 3 [4]'), findsOneWidget); // rebuilt showC now depends on the outer model
    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget); // inner model's a, b, c

    // Now the inner model supports all aspects
    _innerModelAspects = null;
    await tester.tap(find.text('rebuild'));
    await tester.pumpAndSettle();
    expect(find.text('a: 101 [5]'), findsOneWidget); // rebuilt showA now depends on the inner model
    expect(find.text('b: 102 [5]'), findsOneWidget); // rebuilt showB now depends on the inner model
    expect(find.text('c: null [5]'), findsOneWidget); // rebuilt showC now depends on the inner model
    expect(find.text('a: 101 b: 102 c: null'), findsOneWidget); // inner model's a, b, c
  });
}
