// 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';

void main() {
  testWidgets('value is not accessible when not registered', (WidgetTester tester) async {
    expect(() => RestorableNum<num>(0).value, throwsAssertionError);
    expect(() => RestorableDouble(1.0).value, throwsAssertionError);
    expect(() => RestorableInt(1).value, throwsAssertionError);
    expect(() => RestorableString('hello').value, throwsAssertionError);
    expect(() => RestorableBool(true).value, throwsAssertionError);
    expect(() => RestorableNumN<num?>(0).value, throwsAssertionError);
    expect(() => RestorableDoubleN(1.0).value, throwsAssertionError);
    expect(() => RestorableIntN(1).value, throwsAssertionError);
    expect(() => RestorableStringN('hello').value, throwsAssertionError);
    expect(() => RestorableBoolN(true).value, throwsAssertionError);
    expect(() => RestorableTextEditingController().value, throwsAssertionError);
    expect(() => _TestRestorableValue().value, throwsAssertionError);
  });

  testWidgets('work when not in restoration scope', (WidgetTester tester) async {
    await tester.pumpWidget(const _RestorableWidget());

    expect(find.text('hello world'), findsOneWidget);
    final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

    // Initialized to default values.
    expect(state.numValue.value, 99);
    expect(state.doubleValue.value, 123.2);
    expect(state.intValue.value, 42);
    expect(state.stringValue.value, 'hello world');
    expect(state.boolValue.value, false);
    expect(state.controllerValue.value.text, 'FooBar');
    expect(state.objectValue.value, 55);

    // Modify values.
    state.setProperties(() {
      state.numValue.value = 42.2;
      state.doubleValue.value = 441.3;
      state.intValue.value = 10;
      state.stringValue.value = 'guten tag';
      state.boolValue.value = true;
      state.controllerValue.value.text = 'blabla';
      state.objectValue.value = 53;
    });
    await tester.pump();

    expect(state.numValue.value, 42.2);
    expect(state.doubleValue.value, 441.3);
    expect(state.intValue.value, 10);
    expect(state.stringValue.value, 'guten tag');
    expect(state.boolValue.value, true);
    expect(state.controllerValue.value.text, 'blabla');
    expect(state.objectValue.value, 53);
    expect(find.text('guten tag'), findsOneWidget);
  });

  testWidgets('restart and restore', (WidgetTester tester) async {
    await tester.pumpWidget(const RootRestorationScope(
      restorationId: 'root-child',
      child: _RestorableWidget(),
    ));

    expect(find.text('hello world'), findsOneWidget);
    _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

    // Initialized to default values.
    expect(state.numValue.value, 99);
    expect(state.doubleValue.value, 123.2);
    expect(state.intValue.value, 42);
    expect(state.stringValue.value, 'hello world');
    expect(state.boolValue.value, false);
    expect(state.controllerValue.value.text, 'FooBar');
    expect(state.objectValue.value, 55);

    // Modify values.
    state.setProperties(() {
      state.numValue.value = 42.2;
      state.doubleValue.value = 441.3;
      state.intValue.value = 10;
      state.stringValue.value = 'guten tag';
      state.boolValue.value = true;
      state.controllerValue.value.text = 'blabla';
      state.objectValue.value = 53;
    });
    await tester.pump();

    expect(state.numValue.value, 42.2);
    expect(state.doubleValue.value, 441.3);
    expect(state.intValue.value, 10);
    expect(state.stringValue.value, 'guten tag');
    expect(state.boolValue.value, true);
    expect(state.controllerValue.value.text, 'blabla');
    expect(state.objectValue.value, 53);
    expect(find.text('guten tag'), findsOneWidget);

    // Restores to previous values.
    await tester.restartAndRestore();
    final _RestorableWidgetState oldState = state;
    state = tester.state(find.byType(_RestorableWidget));
    expect(state, isNot(same(oldState)));

    expect(state.numValue.value, 42.2);
    expect(state.doubleValue.value, 441.3);
    expect(state.intValue.value, 10);
    expect(state.stringValue.value, 'guten tag');
    expect(state.boolValue.value, true);
    expect(state.controllerValue.value.text, 'blabla');
    expect(state.objectValue.value, 53);
    expect(find.text('guten tag'), findsOneWidget);
  });

  testWidgets('restore to older state', (WidgetTester tester) async {
    await tester.pumpWidget(const RootRestorationScope(
      restorationId: 'root-child',
      child: _RestorableWidget(),
    ));

    expect(find.text('hello world'), findsOneWidget);
    final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

    // Modify values.
    state.setProperties(() {
      state.numValue.value = 42.2;
      state.doubleValue.value = 441.3;
      state.intValue.value = 10;
      state.stringValue.value = 'guten tag';
      state.boolValue.value = true;
      state.nullableNumValue.value = 5.0;
      state.nullableDoubleValue.value = 2.0;
      state.nullableIntValue.value = 1;
      state.nullableStringValue.value = 'hullo';
      state.nullableBoolValue.value = false;
      state.controllerValue.value.text = 'blabla';
      state.objectValue.value = 53;
    });
    await tester.pump();
    expect(find.text('guten tag'), findsOneWidget);

    final TestRestorationData restorationData = await tester.getRestorationData();

    // Modify values.
    state.setProperties(() {
      state.numValue.value = 20;
      state.doubleValue.value = 20.0;
      state.intValue.value = 20;
      state.stringValue.value = 'ciao';
      state.boolValue.value = false;
      state.nullableNumValue.value = 20.0;
      state.nullableDoubleValue.value = 20.0;
      state.nullableIntValue.value = 20;
      state.nullableStringValue.value = 'ni hao';
      state.nullableBoolValue.value = null;
      state.controllerValue.value.text = 'blub';
      state.objectValue.value = 20;
    });
    await tester.pump();
    expect(find.text('ciao'), findsOneWidget);
    final TextEditingController controller = state.controllerValue.value;

    // Restore to previous.
    await tester.restoreFrom(restorationData);
    expect(state.numValue.value, 42.2);
    expect(state.doubleValue.value, 441.3);
    expect(state.intValue.value, 10);
    expect(state.stringValue.value, 'guten tag');
    expect(state.boolValue.value, true);
    expect(state.nullableNumValue.value, 5.0);
    expect(state.nullableDoubleValue.value, 2.0);
    expect(state.nullableIntValue.value, 1);
    expect(state.nullableStringValue.value, 'hullo');
    expect(state.nullableBoolValue.value, false);
    expect(state.controllerValue.value.text, 'blabla');
    expect(state.objectValue.value, 53);
    expect(find.text('guten tag'), findsOneWidget);
    expect(state.controllerValue.value, isNot(same(controller)));

    // Restore to empty data will re-initialize to default values.
    await tester.restoreFrom(TestRestorationData.empty);
    expect(state.numValue.value, 99);
    expect(state.doubleValue.value, 123.2);
    expect(state.intValue.value, 42);
    expect(state.stringValue.value, 'hello world');
    expect(state.boolValue.value, false);
    expect(state.nullableNumValue.value, null);
    expect(state.nullableDoubleValue.value, null);
    expect(state.nullableIntValue.value, null);
    expect(state.nullableStringValue.value, null);
    expect(state.nullableBoolValue.value, null);
    expect(state.controllerValue.value.text, 'FooBar');
    expect(state.objectValue.value, 55);
    expect(find.text('hello world'), findsOneWidget);
  });

  testWidgets('call notifiers when value changes', (WidgetTester tester) async {
    await tester.pumpWidget(const RootRestorationScope(
      restorationId: 'root-child',
      child: _RestorableWidget(),
    ));

    expect(find.text('hello world'), findsOneWidget);
    final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

    final List<String> notifyLog = <String>[];
    state.numValue.addListener(() {
      notifyLog.add('num');
    });
    state.doubleValue.addListener(() {
      notifyLog.add('double');
    });
    state.intValue.addListener(() {
      notifyLog.add('int');
    });
    state.stringValue.addListener(() {
      notifyLog.add('string');
    });
    state.boolValue.addListener(() {
      notifyLog.add('bool');
    });
    state.controllerValue.addListener(() {
      notifyLog.add('controller');
    });
    state.objectValue.addListener(() {
      notifyLog.add('object');
    });

    state.setProperties(() {
      state.numValue.value = 42.2;
    });
    expect(notifyLog.single, 'num');
    notifyLog.clear();

    state.setProperties(() {
      state.doubleValue.value = 42.2;
    });
    expect(notifyLog.single, 'double');
    notifyLog.clear();

    state.setProperties(() {
      state.intValue.value = 45;
    });
    expect(notifyLog.single, 'int');
    notifyLog.clear();

    state.setProperties(() {
      state.stringValue.value = 'bar';
    });
    expect(notifyLog.single, 'string');
    notifyLog.clear();

    state.setProperties(() {
      state.boolValue.value = true;
    });
    expect(notifyLog.single, 'bool');
    notifyLog.clear();

    state.setProperties(() {
      state.controllerValue.value.text = 'foo';
    });
    expect(notifyLog.single, 'controller');
    notifyLog.clear();

    state.setProperties(() {
      state.objectValue.value = 42;
    });
    expect(notifyLog.single, 'object');
    notifyLog.clear();

    await tester.pump();
    expect(find.text('bar'), findsOneWidget);

    // Does not notify when set to same value.
    state.setProperties(() {
      state.numValue.value = 42.2;
      state.doubleValue.value = 42.2;
      state.intValue.value = 45;
      state.stringValue.value = 'bar';
      state.boolValue.value = true;
      state.controllerValue.value.text = 'foo';
    });
    expect(notifyLog, isEmpty);
  });

  testWidgets('RestorableValue calls didUpdateValue', (WidgetTester tester) async {
    await tester.pumpWidget(const RootRestorationScope(
      restorationId: 'root-child',
      child: _RestorableWidget(),
    ));

    expect(find.text('hello world'), findsOneWidget);
    final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

    expect(state.objectValue.didUpdateValueCallCount, 0);

    state.setProperties(() {
      state.objectValue.value = 44;
    });
    expect(state.objectValue.didUpdateValueCallCount, 1);

    await tester.pump();

    state.setProperties(() {
      state.objectValue.value = 44;
    });
    expect(state.objectValue.didUpdateValueCallCount, 1);
  });


  testWidgets('RestorableN types are properly defined', (WidgetTester tester) async {
    await tester.pumpWidget(const RootRestorationScope(
      restorationId: 'root-child',
      child: _RestorableWidget(),
    ));

    expect(find.text('hello world'), findsOneWidget);
    final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));
    state.setProperties(() {
      state.nullableIntValue.value = 24;
      state.nullableDoubleValue.value = 1.5;
    });

    // The following types of asserts do not work. They pass even when the
    // type of `value` is a `num` and not an `int` because `num` is a
    // superclass of `int`. This test is intended to prevent a regression
    // where RestorableIntN's value is of type `num?`, but it is passed into
    // a function which requires an `int?` value. This resulted in Dart
    // compile-time errors.
    //
    // expect(state.nullableIntValue.value, isA<int>());
    // expect(state.nullableIntValue.value.runtimeType, int);

    // A function that takes a nullable int value.
    void takesInt(int? value) {}
    // The following would result in a Dart compile-time error if `value` is
    // a `num?` instead of an `int?`.
    takesInt(state.nullableIntValue.value);

    // A function that takes a nullable double value.
    void takesDouble(double? value) {}
    // The following would result in a Dart compile-time error if `value` is
    // a `num?` instead of a `double?`.
    takesDouble(state.nullableDoubleValue.value);
  });
}

class _TestRestorableValue extends RestorableValue<Object?> {
  @override
  Object createDefaultValue() {
    return 55;
  }

  int didUpdateValueCallCount = 0;

  @override
  void didUpdateValue(Object? oldValue) {
    didUpdateValueCallCount++;
    notifyListeners();
  }

  @override
  Object? fromPrimitives(Object? data) {
    return data;
  }

  @override
  Object? toPrimitives() {
    return value;
  }
}

class _RestorableWidget extends StatefulWidget {
  const _RestorableWidget({Key? key}) : super(key: key);

  @override
  State<_RestorableWidget> createState() => _RestorableWidgetState();
}

class _RestorableWidgetState extends State<_RestorableWidget> with RestorationMixin {
  final RestorableNum<num> numValue = RestorableNum<num>(99);
  final RestorableDouble doubleValue = RestorableDouble(123.2);
  final RestorableInt intValue = RestorableInt(42);
  final RestorableString stringValue = RestorableString('hello world');
  final RestorableBool boolValue = RestorableBool(false);
  final RestorableNumN<num?> nullableNumValue = RestorableNumN<num?>(null);
  final RestorableDoubleN nullableDoubleValue = RestorableDoubleN(null);
  final RestorableIntN nullableIntValue = RestorableIntN(null);
  final RestorableStringN nullableStringValue = RestorableStringN(null);
  final RestorableBoolN nullableBoolValue = RestorableBoolN(null);
  final RestorableTextEditingController controllerValue = RestorableTextEditingController(text: 'FooBar');
  final _TestRestorableValue objectValue = _TestRestorableValue();

  @override
  void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
    registerForRestoration(numValue, 'num');
    registerForRestoration(doubleValue, 'double');
    registerForRestoration(intValue, 'int');
    registerForRestoration(stringValue, 'string');
    registerForRestoration(boolValue, 'bool');
    registerForRestoration(nullableNumValue, 'nullableNum');
    registerForRestoration(nullableDoubleValue, 'nullableDouble');
    registerForRestoration(nullableIntValue, 'nullableInt');
    registerForRestoration(nullableStringValue, 'nullableString');
    registerForRestoration(nullableBoolValue, 'nullableBool');
    registerForRestoration(controllerValue, 'controller');
    registerForRestoration(objectValue, 'object');
  }

  void setProperties(VoidCallback callback) {
    setState(callback);
  }

  @override
  Widget build(BuildContext context) {
    return Text(stringValue.value, textDirection: TextDirection.ltr);
  }

  @override
  String get restorationId => 'widget';
}
