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

import 'restoration.dart';

void main() {
  testWidgets('claims bucket', (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 _TestRestorableWidget(
          restorationId: id,
        ),
      ),
    );
    manager.doSerialization();

    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.bucket?.restorationId, id);
    expect(rawData[childrenMapKey].containsKey(id), isTrue);
    expect(state.property.value, 10);
    expect(rawData[childrenMapKey][id][valuesMapKey]['foo'], 10);
    expect(state.property.log, <String>['createDefaultValue', 'initWithValue', 'toPrimitives']);
    expect(state.toggleBucketLog, isEmpty);
    expect(state.restoreStateLog.single, isNull);
  });

  testWidgets('claimed bucket with data', (WidgetTester tester) async {
    final MockRestorationManager manager = MockRestorationManager();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: _createRawDataSet());

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

    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.bucket!.restorationId, 'child1');
    expect(state.property.value, 22);
    expect(state.property.log, <String>['fromPrimitives', 'initWithValue']);
    expect(state.toggleBucketLog, isEmpty);
    expect(state.restoreStateLog.single, isNull);
  });

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

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

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

    state.property.log.clear();
    state.restoreStateLog.clear();

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

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

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

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

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

    state.property.log.clear();
    state.restoreStateLog.clear();

    // Rename the existing bucket.
    state.injectId('newnewnew');
    manager.doSerialization();

    expect(state.bucket!.restorationId, 'newnewnew');
    expect(state.bucket!.read<int>('foo'), 22);
    expect(state.bucket, same(bucket));
    expect(state.property.log, isEmpty);
    expect(state.restoreStateLog, isEmpty);
    expect(state.toggleBucketLog, isEmpty);
  });

  testWidgets('Disposing widget 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].containsKey('child1'), isTrue);
    await tester.pumpWidget(
      UnmanagedRestorationScope(
        bucket: root,
        child: const _TestRestorableWidget(
          restorationId: 'child1',
        ),
      ),
    );
    manager.doSerialization();
    expect(rawData[childrenMapKey].containsKey('child1'), isTrue);

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

    expect(rawData[childrenMapKey].containsKey('child1'), isFalse);
  });

  testWidgets('toggling id between null and non-null', (WidgetTester tester) async {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    await tester.pumpWidget(
      UnmanagedRestorationScope(
        bucket: root,
        child: const _TestRestorableWidget(
          restorationId: null,
        ),
      ),
    );
    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.bucket, isNull);
    expect(state.property.value, 10); // Initialized to default.
    expect(rawData[childrenMapKey]['child1'][valuesMapKey]['foo'], 22);
    expect(state.property.log, <String>['createDefaultValue', 'initWithValue']);
    state.property.log.clear();
    expect(state.restoreStateLog.single, isNull);
    expect(state.toggleBucketLog, isEmpty);
    state.restoreStateLog.clear();
    state.toggleBucketLog.clear();

    // Change id to non-null.
    await tester.pumpWidget(
      UnmanagedRestorationScope(
        bucket: root,
        child: const _TestRestorableWidget(
          restorationId: 'child1',
        ),
      ),
    );
    manager.doSerialization();
    expect(state.bucket, isNotNull);
    expect(state.bucket!.restorationId, 'child1');
    expect(state.property.value, 10);
    expect(rawData[childrenMapKey]['child1'][valuesMapKey]['foo'], 10);
    expect(state.property.log, <String>['toPrimitives']);
    state.property.log.clear();
    expect(state.restoreStateLog, isEmpty);
    expect(state.toggleBucketLog.single, isNull);
    state.restoreStateLog.clear();
    state.toggleBucketLog.clear();

    final RestorationBucket bucket = state.bucket!;

    // Change id back to null.
    await tester.pumpWidget(
      UnmanagedRestorationScope(
        bucket: root,
        child: const _TestRestorableWidget(
          restorationId: null,
        ),
      ),
    );
    manager.doSerialization();
    expect(state.bucket, isNull);
    expect(rawData[childrenMapKey].containsKey('child1'), isFalse);
    expect(state.property.log, isEmpty);
    expect(state.restoreStateLog, isEmpty);
    expect(state.toggleBucketLog.single, same(bucket));
  });

  testWidgets('move in and out of scope', (WidgetTester tester) async {
    final Key key = GlobalKey();
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    await tester.pumpWidget(
      _TestRestorableWidget(
        key: key,
        restorationId: 'child1',
      ),
    );
    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.bucket, isNull);
    expect(state.property.value, 10); // Initialized to default.
    expect(rawData[childrenMapKey]['child1'][valuesMapKey]['foo'], 22);
    expect(state.property.log, <String>['createDefaultValue', 'initWithValue']);
    state.property.log.clear();
    expect(state.restoreStateLog.single, isNull);
    expect(state.toggleBucketLog, isEmpty);
    state.restoreStateLog.clear();
    state.toggleBucketLog.clear();

    // Move it under a valid scope.
    await tester.pumpWidget(
      UnmanagedRestorationScope(
        bucket: root,
        child: _TestRestorableWidget(
          key: key,
          restorationId: 'child1',
        ),
      ),
    );
    manager.doSerialization();
    expect(state.bucket, isNotNull);
    expect(state.bucket!.restorationId, 'child1');
    expect(state.property.value, 10);
    expect(rawData[childrenMapKey]['child1'][valuesMapKey]['foo'], 10);
    expect(state.property.log, <String>['toPrimitives']);
    state.property.log.clear();
    expect(state.restoreStateLog, isEmpty);
    expect(state.toggleBucketLog.single, isNull);
    state.restoreStateLog.clear();
    state.toggleBucketLog.clear();

    final RestorationBucket bucket = state.bucket!;

    // Move out of scope again.
    await tester.pumpWidget(
      _TestRestorableWidget(
        key: key,
        restorationId: 'child1',
      ),
    );
    manager.doSerialization();
    expect(state.bucket, isNull);
    expect(rawData[childrenMapKey].containsKey('child1'), isFalse);
    expect(state.property.log, isEmpty);
    expect(state.restoreStateLog, isEmpty);
    expect(state.toggleBucketLog.single, same(bucket));
  });

  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 key = GlobalKey();

    await tester.pumpWidget(
      UnmanagedRestorationScope(
        bucket: root,
        child: Row(
          textDirection: TextDirection.ltr,
          children: <Widget>[
            RestorationScope(
              restorationId: 'fixed',
              child: _TestRestorableWidget(
                key: key,
                restorationId: 'moving-child',
              ),
            ),
          ],
        ),
      ),
    );
    manager.doSerialization();
    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.bucket!.restorationId, 'moving-child');
    expect(rawData[childrenMapKey]['fixed'][childrenMapKey].containsKey('moving-child'), isTrue);
    final RestorationBucket bucket = state.bucket!;
    state.property.log.clear();
    state.restoreStateLog.clear();

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

    // Move widget.
    await tester.pumpWidget(
      UnmanagedRestorationScope(
        bucket: root,
        child: Row(
          textDirection: TextDirection.ltr,
          children: <Widget>[
            RestorationScope(
              restorationId: 'fixed',
              child: Container(),
            ),
            _TestRestorableWidget(
              key: key,
              restorationId: 'moving-child',
            ),
          ],
        ),
      ),
    );
    manager.doSerialization();
    expect(state.bucket!.restorationId, 'moving-child');
    expect(state.bucket, same(bucket));
    expect(state.bucket!.read<int>('value'), 11);
    expect(state.property.log, isEmpty);
    expect(state.toggleBucketLog, isEmpty);
    expect(state.restoreStateLog, isEmpty);

    expect(rawData[childrenMapKey]['fixed'], isEmpty);
    expect(rawData[childrenMapKey].containsKey('moving-child'), isTrue);
  });

  testWidgets('restartAndRestore', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      )
    );

    _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.bucket, isNotNull);
    expect(state.property.value, 10); // default
    expect(state.property.log, <String>['createDefaultValue', 'initWithValue', 'toPrimitives']);
    expect(state.restoreStateLog.single, isNull);
    expect(state.toggleBucketLog, isEmpty);
    _clearLogs(state);

    state.setProperties(() {
      state.property.value = 20;
    });
    await tester.pump();
    expect(state.property.value, 20);
    expect(state.property.log, <String>['toPrimitives']);
    expect(state.restoreStateLog, isEmpty);
    expect(state.toggleBucketLog, isEmpty);
    _clearLogs(state);

    final _TestRestorableWidgetState oldState = state;
    await tester.restartAndRestore();
    state = tester.state(find.byType(_TestRestorableWidget));

    expect(state, isNot(same(oldState)));
    expect(state.property.value, 20);
    expect(state.property.log, <String>['fromPrimitives', 'initWithValue']);
    expect(state.restoreStateLog.single, isNull);
    expect(state.toggleBucketLog, isEmpty);
  });

  testWidgets('restore while running', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      ),
    );

    _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));

    state.setProperties(() {
      state.property.value = 20;
    });
    await tester.pump();
    expect(state.property.value, 20);

    final TestRestorationData data = await tester.getRestorationData();

    state.setProperties(() {
      state.property.value = 30;
    });
    await tester.pump();
    expect(state.property.value, 30);
    _clearLogs(state);

    final _TestRestorableWidgetState oldState = state;
    final RestorationBucket oldBucket = oldState.bucket!;
    await tester.restoreFrom(data);
    state = tester.state(find.byType(_TestRestorableWidget));

    expect(state, same(oldState));
    expect(state.property.value, 20);
    expect(state.property.log, <String>['fromPrimitives', 'initWithValue']);
    expect(state.restoreStateLog.single, oldBucket);
    expect(state.toggleBucketLog, isEmpty);
  });

  testWidgets('can register additional property outside of restoreState', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      ),
    );

    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    state.registerAdditionalProperty();
    expect(state.additionalProperty!.value, 11);
    expect(state.additionalProperty!.log, <String>['createDefaultValue', 'initWithValue', 'toPrimitives']);

    state.setProperties(() {
      state.additionalProperty!.value = 33;
    });
    await tester.pump();
    expect(state.additionalProperty!.value, 33);

    final TestRestorationData data = await tester.getRestorationData();

    state.setProperties(() {
      state.additionalProperty!.value = 44;
    });
    await tester.pump();
    expect(state.additionalProperty!.value, 44);
    _clearLogs(state);

    await tester.restoreFrom(data);

    expect(state, same(tester.state(find.byType(_TestRestorableWidget))));
    expect(state.additionalProperty!.value, 33);
    expect(state.property.log, <String>['fromPrimitives', 'initWithValue']);
  });

  testWidgets('cannot register same property twice', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      ),
    );

    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    state.registerAdditionalProperty();
    await tester.pump();
    expect(() => state.registerAdditionalProperty(), throwsAssertionError);
  });

  testWidgets('cannot register under ID that is already in use', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      ),
    );

    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    expect(() => state.registerPropertyUnderSameId(), throwsAssertionError);
  });

  testWidgets('data of disabled property is not stored', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      ),
    );
    _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));

    state.setProperties(() {
      state.property.value = 30;
    });
    await tester.pump();
    expect(state.property.value, 30);
    expect(state.bucket!.read<int>('foo'), 30);
    _clearLogs(state);

    state.setProperties(() {
      state.property.enabled = false;
    });
    await tester.pump();
    expect(state.property.value, 30);
    expect(state.bucket!.contains('foo'), isFalse);
    expect(state.property.log, isEmpty);

    state.setProperties(() {
      state.property.value = 40;
    });
    await tester.pump();
    expect(state.bucket!.contains('foo'), isFalse);
    expect(state.property.log, isEmpty);

    await tester.restartAndRestore();
    state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.property.log, <String>['createDefaultValue', 'initWithValue', 'toPrimitives']);
    expect(state.property.value, 10); // Initialized to default value.
  });

  testWidgets('Enabling property stores its data again', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      ),
    );
    _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    _clearLogs(state);

    state.setProperties(() {
      state.property.enabled = false;
    });
    await tester.pump();
    expect(state.bucket!.contains('foo'), isFalse);
    state.setProperties(() {
      state.property.value = 40;
    });
    await tester.pump();
    expect(state.property.value, 40);
    expect(state.bucket!.contains('foo'), isFalse);
    expect(state.property.log, isEmpty);

    state.setProperties(() {
      state.property.enabled = true;
    });
    await tester.pump();
    expect(state.bucket!.read<int>('foo'), 40);
    expect(state.property.log, <String>['toPrimitives']);

    await tester.restartAndRestore();
    state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.property.log, <String>['fromPrimitives', 'initWithValue']);
    expect(state.property.value, 40);
  });

  testWidgets('Unregistering a property removes its data', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      ),
    );
    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    state.registerAdditionalProperty();
    await tester.pump();
    expect(state.additionalProperty!.value, 11);
    expect(state.bucket!.read<int>('additional'), 11);
    state.unregisterAdditionalProperty();
    await tester.pump();
    expect(state.bucket!.contains('additional'), isFalse);
    expect(() => state.additionalProperty!.value, throwsAssertionError); // No longer registered.

    // Can register the same property again.
    state.registerAdditionalProperty();
    await tester.pump();
    expect(state.additionalProperty!.value, 11);
    expect(state.bucket!.read<int>('additional'), 11);
  });

  testWidgets('Disposing a property unregisters it, but keeps data', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _TestRestorableWidget(
          restorationId: 'widget',
        ),
      ),
    );
    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    state.registerAdditionalProperty();
    await tester.pump();
    expect(state.additionalProperty!.value, 11);
    expect(state.bucket!.read<int>('additional'), 11);

    state.additionalProperty!.dispose();
    await tester.pump();
    expect(state.bucket!.read<int>('additional'), 11);

    // Can register property under same id again.
    state.additionalProperty = _TestRestorableProperty(22);
    state.registerAdditionalProperty();
    await tester.pump();

    expect(state.additionalProperty!.value, 11); // Old value restored.
    expect(state.bucket!.read<int>('additional'), 11);
  });

  test('RestorableProperty throws after disposed', () {
    final RestorableProperty<Object?> property = _TestRestorableProperty(10);
    property.dispose();
    expect(() => property.dispose(), throwsFlutterError);
  });
}

void _clearLogs(_TestRestorableWidgetState state) {
  state.property.log.clear();
  state.additionalProperty?.log.clear();
  state.restoreStateLog.clear();
  state.toggleBucketLog.clear();
}

class _TestRestorableWidget extends StatefulWidget {

  const _TestRestorableWidget({Key? key, this.restorationId}) : super(key: key);

  final String? restorationId;

  @override
  State<_TestRestorableWidget> createState() => _TestRestorableWidgetState();
}

class _TestRestorableWidgetState extends State<_TestRestorableWidget> with RestorationMixin {
  final _TestRestorableProperty property = _TestRestorableProperty(10);
  _TestRestorableProperty? additionalProperty;
  bool _rerigisterAdditionalProperty = false;

  final List<RestorationBucket?> restoreStateLog = <RestorationBucket?>[];
  final List<RestorationBucket?> toggleBucketLog = <RestorationBucket?>[];

  @override
  void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
    restoreStateLog.add(oldBucket);
    registerForRestoration(property, 'foo');
    if (_rerigisterAdditionalProperty && additionalProperty != null) {
      registerForRestoration(additionalProperty!, 'additional');
    }
  }

  @override
  void didToggleBucket(RestorationBucket? oldBucket) {
    toggleBucketLog.add(oldBucket);
    super.didToggleBucket(oldBucket);
  }

  @override
  void dispose() {
    super.dispose();
    property.dispose();
    additionalProperty?.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }

  void setProperties(VoidCallback fn) => setState(fn);

  String? _injectedId;
  void injectId(String id) {
    _injectedId = id;
    didUpdateRestorationId();
  }

  void registerAdditionalProperty({bool reregister = true}) {
    additionalProperty ??= _TestRestorableProperty(11);
    registerForRestoration(additionalProperty!, 'additional');
    _rerigisterAdditionalProperty = reregister;
  }

  void unregisterAdditionalProperty() {
    unregisterFromRestoration(additionalProperty!);
  }

  void registerPropertyUnderSameId() {
    registerForRestoration(_TestRestorableProperty(11), 'foo');
  }

  @override
  String? get restorationId => _injectedId ?? widget.restorationId;
}

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

class _TestRestorableProperty extends RestorableProperty<Object?> {
  _TestRestorableProperty(this._value);

  List<String> log = <String>[];

  @override
  bool get enabled => _enabled;
  bool _enabled = true;
  set enabled(bool value) {
    _enabled = value;
    notifyListeners();
  }

  @override
  Object? createDefaultValue() {
    log.add('createDefaultValue');
    return _value;
  }

  @override
  Object? fromPrimitives(Object? data) {
    log.add('fromPrimitives');
    return data;
  }

  Object? get value {
    assert(isRegistered);
    return _value;
  }
  Object? _value;
  set value(Object? value) {
    _value = value;
    notifyListeners();
  }

  @override
  void initWithValue(Object? v) {
    log.add('initWithValue');
    _value = v;
  }

  @override
  Object? toPrimitives() {
    log.add('toPrimitives');
    return _value;
  }
}
