// 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() {
  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] as Map<Object?, Object?>).containsKey(id), isTrue);
    expect(state.property.value, 10);
    expect((((rawData[childrenMapKey] as Map<Object?, Object?>)[id]! as Map<String, dynamic>)[valuesMapKey] as Map<Object?, Object?>)['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] as Map<String, dynamic>).containsKey('child1'), isTrue);
    await tester.pumpWidget(
      UnmanagedRestorationScope(
        bucket: root,
        child: const _TestRestorableWidget(
          restorationId: 'child1',
        ),
      ),
    );
    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('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(),
      ),
    );
    final _TestRestorableWidgetState state = tester.state(find.byType(_TestRestorableWidget));
    expect(state.bucket, isNull);
    expect(state.property.value, 10); // Initialized to default.
    expect((((rawData[childrenMapKey] as Map<String, dynamic>)['child1'] as Map<String, dynamic>)[valuesMapKey] as Map<String, dynamic>)['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] as Map<String, dynamic>)['child1'] as Map<String, dynamic>)[valuesMapKey] as Map<String, dynamic>)['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(),
      ),
    );
    manager.doSerialization();
    expect(state.bucket, isNull);
    expect((rawData[childrenMapKey] as Map<String, dynamic>).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] as Map<String, dynamic>)['child1'] as Map<String, dynamic>)[valuesMapKey] as Map<String, dynamic>)['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] as Map<String, dynamic>)['child1'] as Map<String, dynamic>)[valuesMapKey] as Map<String, dynamic>)['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] as Map<String, dynamic>).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] as Map<Object?, Object?>)['fixed']! as Map<String, dynamic>)[childrenMapKey] as Map<Object?, Object?>).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] as Map<Object?, Object?>)['fixed'], isEmpty);
    expect((rawData[childrenMapKey] as Map<Object?, Object?>).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;
  }
}
