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

import 'restoration.dart';

void main() {
  test('root bucket values', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket bucket = RestorationBucket.root(manager: manager, rawData: rawData);

    expect(bucket.restorationId, 'root');
    expect(bucket.debugOwner, manager);

    // Bucket contains expected values from rawData.
    expect(bucket.read<int>('value1'), 10);
    expect(bucket.read<String>('value2'), 'Hello');
    expect(bucket.read<String>('value3'), isNull); // Does not exist.
    expect(manager.updateScheduled, isFalse);

    // Can overwrite existing value.
    bucket.write<int>('value1', 22);
    expect(manager.updateScheduled, isTrue);
    expect(bucket.read<int>('value1'), 22);
    manager.doSerialization();
    expect(rawData[valuesMapKey]['value1'], 22);
    expect(manager.updateScheduled, isFalse);

    // Can add a new value.
    bucket.write<bool>('value3', true);
    expect(manager.updateScheduled, isTrue);
    expect(bucket.read<bool>('value3'), true);
    manager.doSerialization();
    expect(rawData[valuesMapKey]['value3'], true);
    expect(manager.updateScheduled, isFalse);

    // Can remove existing value.
    expect(bucket.remove<int>('value1'), 22);
    expect(manager.updateScheduled, isTrue);
    expect(bucket.read<int>('value1'), isNull); // Does not exist anymore.
    manager.doSerialization();
    expect(rawData[valuesMapKey].containsKey('value1'), isFalse);
    expect(manager.updateScheduled, isFalse);

    // Removing non-existing value is no-op.
    expect(bucket.remove<Object>('value4'), isNull);
    expect(manager.updateScheduled, isFalse);

    // Can store null.
    bucket.write<bool?>('value4', null);
    expect(manager.updateScheduled, isTrue);
    expect(bucket.read<int>('value4'), null);
    manager.doSerialization();
    expect(rawData[valuesMapKey].containsKey('value4'), isTrue);
    expect(rawData[valuesMapKey]['value4'], null);
    expect(manager.updateScheduled, isFalse);
  });

  test('child bucket values', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rootRawData = _createRawDataSet();
    final Object debugOwner = Object();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rootRawData);
    final RestorationBucket child = RestorationBucket.child(
      restorationId: 'child1',
      parent: root,
      debugOwner: debugOwner,
    );

    expect(child.restorationId, 'child1');
    expect(child.debugOwner, debugOwner);

    // Bucket contains expected values from rawData.
    expect(child.read<int>('foo'), 22);
    expect(child.read<String>('bar'), isNull); // Does not exist.
    expect(manager.updateScheduled, isFalse);

    // Can overwrite existing value.
    child.write<int>('foo', 44);
    expect(manager.updateScheduled, isTrue);
    expect(child.read<int>('foo'), 44);
    manager.doSerialization();
    expect(rootRawData[childrenMapKey]['child1'][valuesMapKey]['foo'], 44);
    expect(manager.updateScheduled, isFalse);

    // Can add a new value.
    child.write<bool>('value3', true);
    expect(manager.updateScheduled, isTrue);
    expect(child.read<bool>('value3'), true);
    manager.doSerialization();
    expect(rootRawData[childrenMapKey]['child1'][valuesMapKey]['value3'], true);
    expect(manager.updateScheduled, isFalse);

    // Can remove existing value.
    expect(child.remove<int>('foo'), 44);
    expect(manager.updateScheduled, isTrue);
    expect(child.read<int>('foo'), isNull); // Does not exist anymore.
    manager.doSerialization();
    expect(rootRawData[childrenMapKey]['child1'].containsKey('foo'), isFalse);
    expect(manager.updateScheduled, isFalse);

    // Removing non-existing value is no-op.
    expect(child.remove<Object>('value4'), isNull);
    expect(manager.updateScheduled, isFalse);

    // Can store null.
    child.write<bool?>('value4', null);
    expect(manager.updateScheduled, isTrue);
    expect(child.read<int>('value4'), null);
    manager.doSerialization();
    expect(rootRawData[childrenMapKey]['child1'][valuesMapKey].containsKey('value4'), isTrue);
    expect(rootRawData[childrenMapKey]['child1'][valuesMapKey]['value4'], null);
    expect(manager.updateScheduled, isFalse);
  });

  test('claim child with exisiting data', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket bucket = RestorationBucket.root(manager: manager, rawData: rawData);

    final Object debugOwner = Object();
    final RestorationBucket child = bucket.claimChild('child1', debugOwner: debugOwner);

    expect(manager.updateScheduled, isFalse);
    expect(child.restorationId, 'child1');
    expect(child.debugOwner, debugOwner);

    expect(child.read<int>('foo'), 22);
    child.write('bar', 44);
    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(rawData[childrenMapKey]['child1'][valuesMapKey]['bar'], 44);
    expect(manager.updateScheduled, isFalse);
  });

  test('claim child with no exisiting data', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket bucket = RestorationBucket.root(manager: manager, rawData: rawData);

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

    final Object debugOwner = Object();
    final RestorationBucket child = bucket.claimChild('child2', debugOwner: debugOwner);

    expect(manager.updateScheduled, isTrue);
    expect(child.restorationId, 'child2');
    expect(child.debugOwner, debugOwner);

    child.write('foo', 55);
    expect(child.read<int>('foo'), 55);
    manager.doSerialization();

    expect(manager.updateScheduled, isFalse);
    expect(rawData[childrenMapKey].containsKey('child2'), isTrue);
    expect(rawData[childrenMapKey]['child2'][valuesMapKey]['foo'], 55);
  });

  test('claim child that is already claimed throws if not given up', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket bucket = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = bucket.claimChild('child1', debugOwner: 'FirstClaim');

    expect(manager.updateScheduled, isFalse);
    expect(child1.restorationId, 'child1');
    expect(child1.read<int>('foo'), 22);

    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    final RestorationBucket child2 = bucket.claimChild('child1', debugOwner: 'SecondClaim');
    expect(child2.restorationId, 'child1');
    expect(child2.read<int>('foo'), isNull); // Value does not exist in this child.

    // child1 is not given up before running finalizers.
    try {
      manager.doSerialization();
      fail('expected error');
    } on FlutterError catch (e) {
      expect(
        e.message,
        'Multiple owners claimed child RestorationBuckets with the same IDs.\n'
        'The following IDs were claimed multiple times from the parent RestorationBucket(restorationId: root, owner: MockManager):\n'
        ' * "child1" was claimed by:\n'
        '   * SecondClaim\n'
        '   * FirstClaim (current owner)'
      );
    }
  });

  test('claim child that is already claimed does not throw if given up', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket bucket = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = bucket.claimChild('child1', debugOwner: 'FirstClaim');

    expect(manager.updateScheduled, isFalse);
    expect(child1.restorationId, 'child1');
    expect(child1.read<int>('foo'), 22);

    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    final RestorationBucket child2 = bucket.claimChild('child1', debugOwner: 'SecondClaim');
    expect(child2.restorationId, 'child1');
    expect(child2.read<int>('foo'), isNull); // Value does not exist in this child.
    child2.write<int>('bar', 55);

    // give up child1.
    child1.dispose();
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);
    expect(rawData[childrenMapKey]['child1'][valuesMapKey].containsKey('foo'), isFalse);
    expect(rawData[childrenMapKey]['child1'][valuesMapKey]['bar'], 55);
  });

  test('claiming a claimed child twice and only giving it up once throws', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket bucket = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = bucket.claimChild('child1', debugOwner: 'FirstClaim');
    expect(child1.restorationId, 'child1');
    final RestorationBucket child2 = bucket.claimChild('child1', debugOwner: 'SecondClaim');
    expect(child2.restorationId, 'child1');
    child1.dispose();
    final RestorationBucket child3 = bucket.claimChild('child1', debugOwner: 'ThirdClaim');
    expect(child3.restorationId, 'child1');
    expect(manager.updateScheduled, isTrue);
    expect(() => manager.doSerialization(), throwsFlutterError);
  });

  test('unclaiming and then claiming same id gives fresh bucket', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket bucket = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = bucket.claimChild('child1', debugOwner: 'FirstClaim');
    expect(manager.updateScheduled, isFalse);
    expect(child1.read<int>('foo'), 22);
    child1.dispose();
    expect(manager.updateScheduled, isTrue);
    final RestorationBucket child2 = bucket.claimChild('child1', debugOwner: 'SecondClaim');
    expect(child2.read<int>('foo'), isNull);
  });

  test('cleans up raw data if last value/child is dropped', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    expect(rawData.containsKey(childrenMapKey), isTrue);
    final RestorationBucket child = root.claimChild('child1', debugOwner: 'owner');
    child.dispose();
    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(rawData.containsKey(childrenMapKey), isFalse);

    expect(rawData.containsKey(valuesMapKey), isTrue);
    expect(root.remove<int>('value1'), 10);
    expect(root.remove<String>('value2'), 'Hello');
    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(rawData.containsKey(valuesMapKey), isFalse);
  });

  test('dispose deletes data', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = root.claimChild('child1', debugOwner: 'owner1');
    child1.claimChild('child1OfChild1', debugOwner: 'owner1.1');
    child1.claimChild('child2OfChild1', debugOwner: 'owner1.2');
    final RestorationBucket child2 = root.claimChild('child2', debugOwner: 'owner2');

    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    expect(rawData[childrenMapKey].containsKey('child1'), isTrue);
    expect(rawData[childrenMapKey].containsKey('child2'), isTrue);

    child1.dispose();
    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

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

    child2.dispose();
    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    expect(rawData.containsKey(childrenMapKey), isFalse);
  });

  test('rename is no-op if same id', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child = root.claimChild('child1', debugOwner: 'owner1');

    expect(manager.updateScheduled, isFalse);
    expect(child.restorationId, 'child1');
    child.rename('child1');
    expect(manager.updateScheduled, isFalse);
    expect(child.restorationId, 'child1');
    expect(rawData[childrenMapKey].containsKey('child1'), isTrue);
  });

  test('rename to unused id', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child = root.claimChild('child1', debugOwner: 'owner1');
    final Object rawChildData = rawData[childrenMapKey]['child1'] as Object;
    expect(rawChildData, isNotNull);

    expect(manager.updateScheduled, isFalse);
    expect(child.restorationId, 'child1');
    child.rename('new-name');
    expect(child.restorationId, 'new-name');

    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    expect(rawData[childrenMapKey].containsKey('child1'), isFalse);
    expect(rawData[childrenMapKey]['new-name'], rawChildData);
  });

  test('rename to used id throws if id is not given up', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = root.claimChild('child1', debugOwner: 'owner1');
    final RestorationBucket child2 = root.claimChild('child2', debugOwner: 'owner1');
    manager.doSerialization();

    expect(child1.restorationId, 'child1');
    expect(child2.restorationId, 'child2');
    child2.rename('child1');
    expect(child2.restorationId, 'child1');

    expect(manager.updateScheduled, isTrue);
    expect(() => manager.doSerialization(), throwsFlutterError);
  });

  test('rename to used id does not throw if id is given up', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = root.claimChild('child1', debugOwner: 'owner1');
    final RestorationBucket child2 = root.claimChild('child2', debugOwner: 'owner1');
    manager.doSerialization();

    final Object rawChild1Data = rawData[childrenMapKey]['child1'] as Object;
    expect(rawChild1Data, isNotNull);
    final Object rawChild2Data = rawData[childrenMapKey]['child2'] as Object;
    expect(rawChild2Data, isNotNull);

    expect(child1.restorationId, 'child1');
    expect(child2.restorationId, 'child2');
    child2.rename('child1');
    expect(child2.restorationId, 'child1');
    expect(child1.restorationId, 'child1');

    child1.dispose();

    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

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

  test('renaming a to be added child', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final Object rawChild1Data = rawData[childrenMapKey]['child1'] as Object;
    expect(rawChild1Data, isNotNull);

    final RestorationBucket child1 = root.claimChild('child1', debugOwner: 'owner1');
    final RestorationBucket child2 = root.claimChild('child1', debugOwner: 'owner1');

    child2.rename('foo');

    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    expect(child1.restorationId, 'child1');
    expect(child2.restorationId, 'foo');

    expect(rawData[childrenMapKey]['child1'], rawChild1Data);
    expect(rawData[childrenMapKey]['foo'], isEmpty); // new bucket
  });

  test('adopt is no-op if same parent', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = root.claimChild('child1', debugOwner: 'owner1');

    root.adoptChild(child1);
    expect(manager.updateScheduled, isFalse);
    expect(rawData[childrenMapKey].containsKey('child1'), isTrue);
  });

  test('adopt fresh child', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child = RestorationBucket.empty(restorationId: 'fresh-child', debugOwner: 'owner1');

    root.adoptChild(child);
    expect(manager.updateScheduled, isTrue);

    child.write('value', 22);

    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    expect(rawData[childrenMapKey].containsKey('fresh-child'), isTrue);
    expect(rawData[childrenMapKey]['fresh-child'][valuesMapKey]['value'], 22);

    child.write('bar', 'blabla');
    expect(manager.updateScheduled, isTrue);
  });

  test('adopt child that already had a parent', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child = root.claimChild('child1', debugOwner: 'owner1');
    final RestorationBucket childOfChild = child.claimChild('childOfChild', debugOwner: 'owner2');
    childOfChild.write<String>('foo', 'bar');

    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    final Object childOfChildData = rawData[childrenMapKey]['child1'][childrenMapKey]['childOfChild'] as Object;
    expect(childOfChildData, isNotEmpty);

    root.adoptChild(childOfChild);
    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    expect(rawData[childrenMapKey]['child1'].containsKey(childrenMapKey), isFalse); // child1 has no children anymore.
    expect(rawData[childrenMapKey]['childOfChild'], childOfChildData);
  });

  test('adopting child throws if id is already in use and not given up', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child = root.claimChild('child1', debugOwner: 'owner1');
    final RestorationBucket childOfChild = child.claimChild('child1', debugOwner: 'owner2');
    childOfChild.write<String>('foo', 'bar');

    root.adoptChild(childOfChild);
    expect(manager.updateScheduled, isTrue);
    expect(() => manager.doSerialization(), throwsFlutterError);
  });

  test('adopting child does not throw if id is already in use and given up', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child = root.claimChild('child1', debugOwner: 'owner1');
    final RestorationBucket childOfChild = child.claimChild('child1', debugOwner: 'owner2');
    childOfChild.write<String>('foo', 'bar');

    final Object childOfChildData = rawData[childrenMapKey]['child1'][childrenMapKey]['child1'] as Object;
    expect(childOfChildData, isNotEmpty);

    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    root.adoptChild(childOfChild);
    expect(manager.updateScheduled, isTrue);
    child.dispose();
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    expect(rawData[childrenMapKey]['child1'], childOfChildData);
  });

  test('adopting a to-be-added child under an already in use id', () {
    final MockRestorationManager manager = MockRestorationManager();
    final Map<String, dynamic> rawData = _createRawDataSet();
    final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);

    final RestorationBucket child1 = root.claimChild('child1', debugOwner: 'owner1');
    final RestorationBucket child2 = root.claimChild('child2', debugOwner: 'owner1');

    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    final RestorationBucket child1OfChild1 = child1.claimChild('child2', debugOwner: 'owner2');
    child1OfChild1.write<String>('hello', 'world');
    final RestorationBucket child2OfChild1 = child1.claimChild('child2', debugOwner: 'owner2');
    child2OfChild1.write<String>('foo', 'bar');

    root.adoptChild(child2OfChild1);
    child2.dispose();

    expect(manager.updateScheduled, isTrue);
    manager.doSerialization();
    expect(manager.updateScheduled, isFalse);

    expect(rawData[childrenMapKey]['child2'][valuesMapKey]['foo'], 'bar');
    expect(rawData[childrenMapKey]['child1'][childrenMapKey]['child2'][valuesMapKey]['hello'], 'world');
  });

  test('throws when used after dispose', () {
    final RestorationBucket bucket = RestorationBucket.empty(restorationId: 'foo', debugOwner: null);
    bucket.dispose();

    expect(() => bucket.debugOwner, throwsFlutterError);
    expect(() => bucket.restorationId, throwsFlutterError);
    expect(() => bucket.read<int>('foo'), throwsFlutterError);
    expect(() => bucket.write('foo', 10), throwsFlutterError);
    expect(() => bucket.remove<int>('foo'), throwsFlutterError);
    expect(() => bucket.contains('foo'), throwsFlutterError);
    expect(() => bucket.claimChild('child', debugOwner: null), throwsFlutterError);
    final RestorationBucket child = RestorationBucket.empty(restorationId: 'child', debugOwner: null);
    expect(() => bucket.adoptChild(child), throwsFlutterError);
    expect(() => bucket.rename('bar'), throwsFlutterError);
    expect(() => bucket.dispose(), throwsFlutterError);
  });
}

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