// 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({
    super.key,
    this.a,
    this.b,
    this.c,
    this.aspects,
    required super.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({ super.key, required this.fieldName });

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