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

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

    final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));
    expect(find.text('Hello World 100'), findsOneWidget);
    expect(state.doubleValue, 1.0);

    state.setValues('Guten Morgen', 200, 33.4);
    await tester.pump();

    expect(find.text('Guten Morgen 200'), findsOneWidget);
    expect(state.doubleValue, 33.4);

    await tester.restartAndRestore();

    expect(find.text('Guten Morgen 200'), findsOneWidget);
    expect(find.text('Hello World 100'), findsNothing);
    final _RestorableWidgetState restoredState = tester.state(find.byType(_RestorableWidget));
    expect(restoredState, isNot(same(state)));
    expect(restoredState.doubleValue, 1.0);
  });

  testWidgets('restore from previous restoration data', (WidgetTester tester) async {
    await tester.pumpWidget(
      const RootRestorationScope(
        restorationId: 'root-child',
        child: _RestorableWidget(
          restorationId: 'restorable-widget',
        ),
      ),
    );

    final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));
    expect(find.text('Hello World 100'), findsOneWidget);
    expect(state.doubleValue, 1.0);

    state.setValues('Guten Morgen', 200, 33.4);
    await tester.pump();

    expect(find.text('Guten Morgen 200'), findsOneWidget);
    expect(state.doubleValue, 33.4);

    final TestRestorationData data = await tester.getRestorationData();

    state.setValues('See you later!', 400, 123.5);
    await tester.pump();

    expect(find.text('See you later! 400'), findsOneWidget);
    expect(state.doubleValue, 123.5);

    await tester.restoreFrom(data);

    expect(tester.state(find.byType(_RestorableWidget)), same(state));
    expect(find.text('Guten Morgen 200'), findsOneWidget);
    expect(state.doubleValue, 123.5);
  });
}

class _RestorableWidget extends StatefulWidget {
  const _RestorableWidget({Key key, this.restorationId}) : super(key: key);

  final String restorationId;

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

class _RestorableWidgetState extends State<_RestorableWidget> with RestorationMixin {
  final RestorableString stringValue = RestorableString('Hello World');
  final RestorableInt intValue = RestorableInt(100);

  double doubleValue = 1.0; // Not restorable.

  @override
  void restoreState(RestorationBucket oldBucket, bool initialRestore) {
    registerForRestoration(stringValue, 'string');
    registerForRestoration(intValue, 'int');
  }

  void setValues(String s, int i, double d) {
    setState(() {
      stringValue.value = s;
      intValue.value = i;
      doubleValue = d;
    });
  }

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

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