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

import 'restoration.dart';

void main() {
  group('UnmanagedRestorationScope', () {
    testWidgets('makes bucket available to descendants', (WidgetTester tester) async {
      final RestorationBucket bucket1 = RestorationBucket.empty(
        restorationId: 'foo',
        debugOwner: 'owner',
      );

      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: bucket1,
          child: const BucketSpy(),
        ),
      );

      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket, bucket1);

      // Notifies when bucket changes.
      final RestorationBucket bucket2 = RestorationBucket.empty(
        restorationId: 'foo2',
        debugOwner: 'owner',
      );
      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: bucket2,
          child: const BucketSpy(),
        ),
      );
      expect(state.bucket, bucket2);
    });

    testWidgets('null bucket disables restoration', (WidgetTester tester) async {
      await tester.pumpWidget(
        const UnmanagedRestorationScope(
          child: BucketSpy(),
        ),
      );
      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket, isNull);
    });
  });

  group('RestorationScope', () {
    testWidgets('makes bucket available to descendants', (WidgetTester tester) async {
      const String id = 'hello world 1234';
      final MockRestorationManager manager = MockRestorationManager();
      final Map<String, dynamic> rawData = <String, dynamic>{};
      final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);
      expect(rawData, isEmpty);

      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: const RestorationScope(
            restorationId: id,
            child: BucketSpy(),
          ),
        ),
      );
      manager.doSerialization();

      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket!.restorationId, id);
      expect((rawData[childrenMapKey] as Map<Object?, Object?>).containsKey(id), isTrue);
    });

    testWidgets('bucket for descendants contains data claimed from parent', (WidgetTester tester) async {
      final MockRestorationManager manager = MockRestorationManager();
      final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: _createRawDataSet());

      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: const RestorationScope(
            restorationId: 'child1',
            child: BucketSpy(),
          ),
        ),
      );
      manager.doSerialization();

      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket!.restorationId, 'child1');
      expect(state.bucket!.read<int>('foo'), 22);
    });

    testWidgets('renames existing bucket when new ID is provided', (WidgetTester tester) async {
      final MockRestorationManager manager = MockRestorationManager();
      final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: _createRawDataSet());

      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: const RestorationScope(
            restorationId: 'child1',
            child: BucketSpy(),
          ),
        ),
      );
      manager.doSerialization();

      // Claimed existing bucket with data.
      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket!.restorationId, 'child1');
      expect(state.bucket!.read<int>('foo'), 22);
      final RestorationBucket bucket = state.bucket!;

      // Rename the existing bucket.
      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: const RestorationScope(
            restorationId: 'something else',
            child: BucketSpy(),
          ),
        ),
      );
      manager.doSerialization();

      expect(state.bucket!.restorationId, 'something else');
      expect(state.bucket!.read<int>('foo'), 22);
      expect(state.bucket, same(bucket));
    });

    testWidgets('Disposing a scope removes its data', (WidgetTester tester) async {
      final MockRestorationManager manager = MockRestorationManager();
      final Map<String, dynamic> rawData = _createRawDataSet();
      final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

      expect((rawData[childrenMapKey] as Map<String, dynamic>).containsKey('child1'), isTrue);
      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: const RestorationScope(
            restorationId: 'child1',
            child: BucketSpy(),
          ),
        ),
      );
      manager.doSerialization();
      expect((rawData[childrenMapKey] as Map<String, dynamic>).containsKey('child1'), isTrue);

      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: Container(),
        ),
      );
      manager.doSerialization();

      expect((rawData[childrenMapKey] as Map<String, dynamic>).containsKey('child1'), isFalse);
    });

    testWidgets('no bucket for descendants when id is null', (WidgetTester tester) async {
      final MockRestorationManager manager = MockRestorationManager();
      final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: <String, dynamic>{});

      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: const RestorationScope(
            restorationId: null,
            child: BucketSpy(),
          ),
        ),
      );
      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket, isNull);

      // Change id to non-null.
      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: const RestorationScope(
            restorationId: 'foo',
            child: BucketSpy(),
          ),
        ),
      );
      manager.doSerialization();
      expect(state.bucket, isNotNull);
      expect(state.bucket!.restorationId, 'foo');

      // Change id back to null.
      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: const RestorationScope(
            restorationId: null,
            child: BucketSpy(),
          ),
        ),
      );
      manager.doSerialization();
      expect(state.bucket, isNull);
    });

    testWidgets('no bucket for descendants when scope is null', (WidgetTester tester) async {
      final Key scopeKey = GlobalKey();

      await tester.pumpWidget(
        RestorationScope(
          key: scopeKey,
          restorationId: 'foo',
          child: const BucketSpy(),
        ),
      );
      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket, isNull);

      // Move it under a valid scope.
      final MockRestorationManager manager = MockRestorationManager();
      final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: <String, dynamic>{});
      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: RestorationScope(
            key: scopeKey,
            restorationId: 'foo',
            child: const BucketSpy(),
          ),
        ),
      );
      manager.doSerialization();
      expect(state.bucket, isNotNull);
      expect(state.bucket!.restorationId, 'foo');

      // Move out of scope again.
      await tester.pumpWidget(
        RestorationScope(
          key: scopeKey,
          restorationId: 'foo',
          child: const BucketSpy(),
        ),
      );
      manager.doSerialization();
      expect(state.bucket, isNull);
    });

    testWidgets('no bucket for descendants when scope and id are null', (WidgetTester tester) async {
      await tester.pumpWidget(
        const RestorationScope(
          restorationId: null,
          child: BucketSpy(),
        ),
      );
      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket, isNull);
    });

    testWidgets('moving scope moves its data', (WidgetTester tester) async {
      final MockRestorationManager manager = MockRestorationManager();
      final Map<String, dynamic> rawData = <String, dynamic>{};
      final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);
      final Key scopeKey = GlobalKey();

      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: Row(
            textDirection: TextDirection.ltr,
            children: <Widget>[
              RestorationScope(
                restorationId: 'fixed',
                child: RestorationScope(
                  key: scopeKey,
                  restorationId: 'moving-child',
                  child: const BucketSpy(),
                ),
              ),
            ],
          ),
        ),
      );
      manager.doSerialization();
      final BucketSpyState state = tester.state(find.byType(BucketSpy));
      expect(state.bucket!.restorationId, 'moving-child');
      expect((((rawData[childrenMapKey] as Map<Object?, Object?>)['fixed']! as Map<String, dynamic>)[childrenMapKey] as Map<Object?, Object?>).containsKey('moving-child'), isTrue);
      final RestorationBucket bucket = state.bucket!;

      state.bucket!.write('value', 11);
      manager.doSerialization();

      // Move scope.
      await tester.pumpWidget(
        UnmanagedRestorationScope(
          bucket: root,
          child: Row(
            textDirection: TextDirection.ltr,
            children: <Widget>[
              RestorationScope(
                restorationId: 'fixed',
                child: Container(),
              ),
              RestorationScope(
                key: scopeKey,
                restorationId: 'moving-child',
                child: const BucketSpy(),
              ),
            ],
          ),
        ),
      );
      manager.doSerialization();
      expect(state.bucket!.restorationId, 'moving-child');
      expect(state.bucket, same(bucket));
      expect(state.bucket!.read<int>('value'), 11);

      expect((rawData[childrenMapKey] as Map<Object?, Object?>)['fixed'], isEmpty);
      expect((rawData[childrenMapKey] as Map<Object?, Object?>).containsKey('moving-child'), isTrue);
    });
  });
}

Map<String, dynamic> _createRawDataSet() {
  return <String, dynamic>{
    valuesMapKey: <String, dynamic>{
      'value1' : 10,
      'value2' : 'Hello',
    },
    childrenMapKey: <String, dynamic>{
      'child1' : <String, dynamic>{
        valuesMapKey : <String, dynamic>{
          'foo': 22,
        },
      },
      'child2' : <String, dynamic>{
        valuesMapKey : <String, dynamic>{
          'bar': 33,
        },
      },
    },
  };
}
