// 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 'dart:async';

import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

import 'restoration.dart';

void main() {
  group('RestorationManager', () {
    testWidgets('root bucket retrieval', (WidgetTester tester) async {
      final List<MethodCall> callsToEngine = <MethodCall>[];
      final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
      tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
        callsToEngine.add(call);
        return result.future;
      });

      final RestorationManager manager = RestorationManager();
      final Future<RestorationBucket?> rootBucketFuture = manager.rootBucket;
      RestorationBucket? rootBucket;
      rootBucketFuture.then((RestorationBucket? bucket) {
        rootBucket = bucket;
      });
      expect(rootBucketFuture, isNotNull);
      expect(rootBucket, isNull);

      // Accessing rootBucket again gives same future.
      expect(manager.rootBucket, same(rootBucketFuture));

      // Engine has only been contacted once.
      expect(callsToEngine, hasLength(1));
      expect(callsToEngine.single.method, 'get');

      // Complete the engine request.
      result.complete(_createEncodedRestorationData1());
      await tester.pump();

      // Root bucket future completed.
      expect(rootBucket, isNotNull);

      // Root bucket contains the expected data.
      expect(rootBucket!.read<int>('value1'), 10);
      expect(rootBucket!.read<String>('value2'), 'Hello');
      final RestorationBucket child = rootBucket!.claimChild('child1', debugOwner: null);
      expect(child.read<int>('another value'), 22);

      // Accessing the root bucket again completes synchronously with same bucket.
      RestorationBucket? synchronousBucket;
      manager.rootBucket.then((RestorationBucket? bucket) {
        synchronousBucket = bucket;
      });
      expect(synchronousBucket, isNotNull);
      expect(synchronousBucket, same(rootBucket));
    });

    testWidgets('root bucket received from engine before retrieval', (WidgetTester tester) async {
      SystemChannels.restoration.setMethodCallHandler(null);
      final List<MethodCall> callsToEngine = <MethodCall>[];
      tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) async {
        callsToEngine.add(call);
        return null;
      });
      final RestorationManager manager = RestorationManager();

      await _pushDataFromEngine(_createEncodedRestorationData1());

      RestorationBucket? rootBucket;
      manager.rootBucket.then((RestorationBucket? bucket) => rootBucket = bucket);
      // Root bucket is available synchronously.
      expect(rootBucket, isNotNull);
      // Engine was never asked.
      expect(callsToEngine, isEmpty);
    });

    testWidgets('root bucket received while engine retrieval is pending', (WidgetTester tester) async {
      SystemChannels.restoration.setMethodCallHandler(null);
      final List<MethodCall> callsToEngine = <MethodCall>[];
      final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
      tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
        callsToEngine.add(call);
        return result.future;
      });
      final RestorationManager manager = RestorationManager();

      RestorationBucket? rootBucket;
      manager.rootBucket.then((RestorationBucket? bucket) => rootBucket = bucket);
      expect(rootBucket, isNull);
      expect(callsToEngine.single.method, 'get');

      await _pushDataFromEngine(_createEncodedRestorationData1());
      expect(rootBucket, isNotNull);
      expect(rootBucket!.read<int>('value1'), 10);

      result.complete(_createEncodedRestorationData2());
      await tester.pump();

      RestorationBucket? rootBucket2;
      manager.rootBucket.then((RestorationBucket? bucket) => rootBucket2 = bucket);
      expect(rootBucket2, isNotNull);
      expect(rootBucket2, same(rootBucket));
      expect(rootBucket2!.read<int>('value1'), 10);
      expect(rootBucket2!.contains('foo'), isFalse);
    });

    testWidgets('root bucket is properly replaced when new data is available', (WidgetTester tester) async {
      tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) async {
        return _createEncodedRestorationData1();
      });
      final RestorationManager manager = RestorationManager();
      RestorationBucket? rootBucket;
      manager.rootBucket.then((RestorationBucket? bucket) {
        rootBucket = bucket;
      });
      await tester.pump();
      expect(rootBucket, isNotNull);
      expect(rootBucket!.read<int>('value1'), 10);
      final RestorationBucket child = rootBucket!.claimChild('child1', debugOwner: null);
      expect(child.read<int>('another value'), 22);

      bool rootReplaced = false;
      RestorationBucket? newRoot;
      manager.addListener(() {
        rootReplaced = true;
        manager.rootBucket.then((RestorationBucket? bucket) {
          newRoot = bucket;
        });
        // The new bucket is available synchronously.
        expect(newRoot, isNotNull);
      });

      // Send new Data.
      await _pushDataFromEngine(_createEncodedRestorationData2());

      expect(rootReplaced, isTrue);
      expect(newRoot, isNot(same(rootBucket)));

      child.dispose();

      expect(newRoot!.read<int>('foo'), 33);
      expect(newRoot!.read<int>('value1'), null);
      final RestorationBucket newChild = newRoot!.claimChild('childFoo', debugOwner: null);
      expect(newChild.read<String>('bar'), 'Hello');
    });

    testWidgets('returns null as root bucket when restoration is disabled', (WidgetTester tester) async {
      final List<MethodCall> callsToEngine = <MethodCall>[];
      final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
      tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call)  {
        callsToEngine.add(call);
        return result.future;
      });
      int listenerCount = 0;
      final RestorationManager manager = RestorationManager()..addListener(() {
        listenerCount++;
      });
      RestorationBucket? rootBucket;
      bool rootBucketResolved = false;
      manager.rootBucket.then((RestorationBucket? bucket) {
        rootBucketResolved = true;
        rootBucket = bucket;
      });
      await tester.pump();
      expect(rootBucketResolved, isFalse);
      expect(listenerCount, 0);

      result.complete(_packageRestorationData(enabled: false));
      await tester.pump();
      expect(rootBucketResolved, isTrue);
      expect(rootBucket, isNull);

      // Switch to non-null.
      await _pushDataFromEngine(_createEncodedRestorationData1());
      expect(listenerCount, 1);
      manager.rootBucket.then((RestorationBucket? bucket) {
        rootBucket = bucket;
      });
      expect(rootBucket, isNotNull);

      // Switch to null again.
      await _pushDataFromEngine(_packageRestorationData(enabled: false));
      expect(listenerCount, 2);
      manager.rootBucket.then((RestorationBucket? bucket) {
        rootBucket = bucket;
      });
      expect(rootBucket, isNull);
    });

    testWidgets('flushData', (WidgetTester tester) async {
      final List<MethodCall> callsToEngine = <MethodCall>[];
      final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
      tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
        callsToEngine.add(call);
        return result.future;
      });

      final RestorationManager manager = RestorationManager();
      final Future<RestorationBucket?> rootBucketFuture = manager.rootBucket;
      RestorationBucket? rootBucket;
      rootBucketFuture.then((RestorationBucket? bucket) {
        rootBucket = bucket;
      });
      result.complete(_createEncodedRestorationData1());
      await tester.pump();
      expect(rootBucket, isNotNull);
      callsToEngine.clear();

      // Schedule a frame.
      SchedulerBinding.instance.ensureVisualUpdate();
      rootBucket!.write('foo', 1);
      // flushData is no-op because frame is scheduled.
      manager.flushData();
      expect(callsToEngine, isEmpty);
      // Data is flushed at the end of the frame.
      await tester.pump();
      expect(callsToEngine, hasLength(1));
      callsToEngine.clear();

      // flushData without frame sends data directly.
      rootBucket!.write('foo', 2);
      manager.flushData();
      expect(callsToEngine, hasLength(1));
    });

    testWidgets('isReplacing', (WidgetTester tester) async {
      final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
      tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
        return result.future;
      });

      final TestRestorationManager manager = TestRestorationManager();
      expect(manager.isReplacing, isFalse);

      RestorationBucket? rootBucket;
      manager.rootBucket.then((RestorationBucket? bucket) {
        rootBucket = bucket;
      });
      result.complete(_createEncodedRestorationData1());
      await tester.idle();
      expect(rootBucket, isNotNull);
      expect(rootBucket!.isReplacing, isFalse);
      expect(manager.isReplacing, isFalse);
      tester.binding.scheduleFrame();
      await tester.pump();
      expect(manager.isReplacing, isFalse);
      expect(rootBucket!.isReplacing, isFalse);

      manager.receiveDataFromEngine(enabled: true, data: null);
      RestorationBucket? rootBucket2;
      manager.rootBucket.then((RestorationBucket? bucket) {
        rootBucket2 = bucket;
      });
      expect(rootBucket2, isNotNull);
      expect(rootBucket2, isNot(same(rootBucket)));
      expect(manager.isReplacing, isTrue);
      expect(rootBucket2!.isReplacing, isTrue);
      await tester.idle();
      expect(manager.isReplacing, isTrue);
      expect(rootBucket2!.isReplacing, isTrue);
      tester.binding.scheduleFrame();
      await tester.pump();
      expect(manager.isReplacing, isFalse);
      expect(rootBucket2!.isReplacing, isFalse);

      manager.receiveDataFromEngine(enabled: false, data: null);
      RestorationBucket? rootBucket3;
      manager.rootBucket.then((RestorationBucket? bucket) {
        rootBucket3 = bucket;
      });
      expect(rootBucket3, isNull);
      expect(manager.isReplacing, isFalse);
      await tester.idle();
      expect(manager.isReplacing, isFalse);
      tester.binding.scheduleFrame();
      await tester.pump();
      expect(manager.isReplacing, isFalse);
    });
  });

  test('debugIsSerializableForRestoration', () {
    expect(debugIsSerializableForRestoration(Object()), isFalse);
    expect(debugIsSerializableForRestoration(Container()), isFalse);

    expect(debugIsSerializableForRestoration(null), isTrue);
    expect(debugIsSerializableForRestoration(147823), isTrue);
    expect(debugIsSerializableForRestoration(12.43), isTrue);
    expect(debugIsSerializableForRestoration('Hello World'), isTrue);
    expect(debugIsSerializableForRestoration(<int>[12, 13, 14]), isTrue);
    expect(debugIsSerializableForRestoration(<String, int>{'v1' : 10, 'v2' : 23}), isTrue);
    expect(debugIsSerializableForRestoration(<String, dynamic>{
      'hello': <int>[12, 12, 12],
      'world': <int, bool>{
        1: true,
        2: false,
        4: true,
      },
    }), isTrue);
  });
}

Future<void> _pushDataFromEngine(Map<dynamic, dynamic> data) async {
  await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
    'flutter/restoration',
    const StandardMethodCodec().encodeMethodCall(MethodCall('push', data)),
    (_) { },
  );
}

Map<dynamic, dynamic> _createEncodedRestorationData1() {
  final Map<String, dynamic> data = <String, dynamic>{
    valuesMapKey: <String, dynamic>{
      'value1' : 10,
      'value2' : 'Hello',
    },
    childrenMapKey: <String, dynamic>{
      'child1' : <String, dynamic>{
        valuesMapKey : <String, dynamic>{
          'another value': 22,
        },
      },
    },
  };
  return _packageRestorationData(data: data);
}

Map<dynamic, dynamic> _createEncodedRestorationData2() {
  final Map<String, dynamic> data = <String, dynamic>{
    valuesMapKey: <String, dynamic>{
      'foo' : 33,
    },
    childrenMapKey: <String, dynamic>{
      'childFoo' : <String, dynamic>{
        valuesMapKey : <String, dynamic>{
          'bar': 'Hello',
        },
      },
    },
  };
  return _packageRestorationData(data: data);
}

Map<dynamic, dynamic> _packageRestorationData({bool enabled = true, Map<dynamic, dynamic>? data}) {
  final ByteData? encoded = const StandardMessageCodec().encodeMessage(data);
  return <dynamic, dynamic>{
    'enabled': enabled,
    'data': encoded?.buffer.asUint8List(encoded.offsetInBytes, encoded.lengthInBytes),
  };
}

class TestRestorationManager extends RestorationManager {
  void receiveDataFromEngine({required bool enabled, required Uint8List? data}) {
    handleRestorationUpdateFromEngine(enabled: enabled, data: data);
  }
}
