// Copyright 2018 The Fuchsia 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:convert' show json;
import 'dart:typed_data';

// TODO: investigate whether we can get rid of the implementation_imports.
// ignore_for_file: implementation_imports
import 'package:lib.app.dart/logging.dart';
import 'package:sledge/sledge.dart';
import 'package:sledge/src/document/change.dart';
import 'package:sledge/src/uint8list_ops.dart';
import 'package:test/test.dart';

import 'helpers.dart';

Map<String, BaseType> flatSchema() {
  return <String, BaseType>{
    'someBool': Boolean(),
    'someInteger': Integer()
  };
}

Map<String, BaseType> schemaWithEmbeddedSchema() {
  Schema schema = Schema(flatSchema());
  return <String, BaseType>{'foo': schema, 'bar': LastOneWinsString()};
}

void main() {
  setupLogger();

  test('Create flat schema', () {
    Schema(flatSchema());
  });

  test('Create schema with embedded schema.', () {
    Schema(schemaWithEmbeddedSchema());
  });

  test('Serialize and deserialize flat schema', () {
    Schema schema1 = Schema(flatSchema());
    final json1 = json.encode(schema1);
    Schema schema2 = Schema.fromJson(json.decode(json1));
    final json2 = json.encode(schema2);
    expect(json1, equals(json2));
  });

  test('Serialize and deserialize schema with embedded schema', () {
    Schema schema1 = Schema(schemaWithEmbeddedSchema());
    final json1 = json.encode(schema1);
    Schema schema2 = Schema.fromJson(json.decode(json1));
    final json2 = json.encode(schema2);
    expect(json1, equals(json2));
  });

  test('Verify that two identical schemes result in identical hashes', () {
    Map<String, BaseType> schemaDescription1 = <String, BaseType>{
      'someBool': Boolean(),
      'someInteger': Integer()
    };
    Map<String, BaseType> schemaDescription2 = <String, BaseType>{
      'someInteger': Integer(),
      'someBool': Boolean(),
    };
    Schema schema1 = Schema(schemaDescription1);
    Schema schema2 = Schema(schemaDescription2);
    expect(schema1.hash, equals(schema2.hash));
  });

  test('Verify that two different schemes result in different hashes', () {
    Map<String, BaseType> schemaDescription1 = <String, BaseType>{
      'someBool': Boolean(),
      'someInteger': Integer()
    };
    Map<String, BaseType> schemaDescription2 = <String, BaseType>{
      'someBool': Boolean(),
    };
    Map<String, BaseType> schemaDescription3 = <String, BaseType>{
      'someBool_': Boolean(),
      'someInteger': Integer()
    };
    Schema schema1 = Schema(schemaDescription1);
    Schema schema2 = Schema(schemaDescription2);
    Schema schema3 = Schema(schemaDescription3);
    expect(schema1.hash, isNot(equals(schema2.hash)));
    expect(schema1.hash, isNot(equals(schema3.hash)));
  });

  test('Verify that schemas can not be modified after their creation', () {
    Map<String, BaseType> schemaDescription = <String, BaseType>{
      'someBool': Boolean(),
    };
    Schema schema = Schema(schemaDescription);
    Uint8List hash1 = schema.hash;
    schemaDescription['foo'] = Integer();
    Uint8List hash2 = schema.hash;
    expect(hash1, equals(hash2));
  });

  test('Verify exception with invalid field names', () {
    Map<String, BaseType> schemaDescription = <String, BaseType>{
      'foo.bar': Boolean(),
    };
    expect(() {
      Schema(schemaDescription);
    }, throwsA(const TypeMatcher<ArgumentError>()));
  });

  test('Verify fieldAtPath', () {
    final schema = Schema(schemaWithEmbeddedSchema());
    expect(schema.fieldAtPath(null), equals(null));
    expect(schema.fieldAtPath(''), equals(null));
    expect(schema.fieldAtPath('.'), equals(null));
    expect(schema.fieldAtPath('..'), equals(null));
    expect(schema.fieldAtPath('xyz'), equals(null));
    expect(schema.fieldAtPath('foo'), TypeMatcher<Schema>());
    expect(schema.fieldAtPath('bar'), TypeMatcher<LastOneWinsString>());
    expect(schema.fieldAtPath('foo.'), equals(null));
    expect(schema.fieldAtPath('bar.'), equals(null));
    expect(schema.fieldAtPath('foo.someBool'), TypeMatcher<Boolean>());
    expect(schema.fieldAtPath('foo.someBool.'), equals(null));
  });

  test('Instantiate and initialize a Sledge document', () async {
    // Create schemas.
    Map<String, BaseType> schemaDescription = <String, BaseType>{
      'someBool': Boolean(),
      'someInteger': Integer()
    };
    Schema schema = Schema(schemaDescription);
    Map<String, BaseType> schemaDescription2 = <String, BaseType>{
      'foo': schema
    };
    Schema schema2 = Schema(schemaDescription2);

    // Create a new Sledge document.
    Sledge sledge = newSledgeForTesting();
    Document doc;
    await sledge.runInTransaction(() async {
      doc = await sledge.getDocument(DocumentId(schema2));
    });
    // Read and write properties of a Sledge document.
    expect(doc['foo']['someBool'].value, equals(false));
    expect(doc['foo']['someInteger'].value, equals(0));
    await sledge.runInTransaction(() async {
      doc['foo']['someBool'].value = true;
      doc['foo']['someInteger'].value = 42;
    });
    expect(doc['foo']['someBool'].value, equals(true));
    expect(doc['foo']['someInteger'].value, equals(42));
  });

  test('Last One Wins basic types.', () async {
    // Create schemas.
    Map<String, BaseType> schemaDescription = <String, BaseType>{
      'someBool': Boolean(),
      'someInteger': Integer(),
      'someDouble': Double(),
      'someString': LastOneWinsString()
    };
    Schema schema = Schema(schemaDescription);

    // Create a new Sledge document.
    Sledge sledge = newSledgeForTesting();
    Document doc;
    await sledge.runInTransaction(() async {
      doc = await sledge.getDocument(DocumentId(schema));
    });

    // Read and write properties of a Sledge document.
    expect(doc['someBool'].value, equals(false));
    expect(doc['someInteger'].value, equals(0));
    expect(doc['someDouble'].value, equals(0.0));
    expect(doc['someString'].value, equals(''));

    await sledge.runInTransaction(() async {
      doc['someBool'].value = true;
      doc['someInteger'].value = 42;
      doc['someDouble'].value = 10.5;
      doc['someString'].value = 'abacaba';
    });

    expect(doc['someBool'].value, equals(true));
    expect(doc['someInteger'].value, equals(42));
    expect(doc['someDouble'].value, equals(10.5));
    expect(doc['someString'].value, equals('abacaba'));
  });

  test('Integration of PosNegCounter with Sledge', () async {
    // Create Schema.
    Map<String, BaseType> schemaDescription = <String, BaseType>{
      'cnt': IntCounter(),
      'cnt_d': DoubleCounter()
    };
    Schema schema = Schema(schemaDescription);

    // Create a new Sledge document.
    Sledge sledge = newSledgeForTesting();
    Document doc;
    await sledge.runInTransaction(() async {
      doc = await sledge.getDocument(DocumentId(schema));
    });

    // Modify and get value of PosNegCounter.
    expect(doc['cnt'].value, equals(0));
    expect(doc['cnt_d'].value, equals(0.0));
    await sledge.runInTransaction(() async {
      doc['cnt'].add(5);
    });
    expect(doc['cnt'].value, equals(5));
    await sledge.runInTransaction(() async {
      doc['cnt'].add(-3);
      doc['cnt_d'].add(-5.2);
    });
    expect(doc['cnt'].value, equals(2));
    expect(doc['cnt_d'].value, equals(-5.2));
    await sledge.runInTransaction(() async {
      doc['cnt_d'].add(3.12);
    });
    expect(doc['cnt_d'].value, equals(-2.08));
  });

  // TODO: add tests for BytelistMap and BytelistSet.

  test('Integration of OrderedList with Sledge', () async {
    Map<String, BaseType> schemaDescription = <String, BaseType>{
      'list': OrderedList()
    };
    Schema schema = Schema(schemaDescription);

    // Create a new Sledge document.
    Sledge sledge = newSledgeForTesting();
    Document doc;
    await sledge.runInTransaction(() async {
      doc = await sledge.getDocument(DocumentId(schema));
    });

    // Apply modifications to OrderedList.
    expect(doc['list'].toList(), equals([]));
    await sledge.runInTransaction(() async {
      doc['list'].insert(0, Uint8List.fromList([1]));
    });
    expect(doc['list'].toList().length, equals(1));
    expect(doc['list'][0].toList(), equals([1]));
    await sledge.runInTransaction(() async {
      doc['list'].insert(1, Uint8List.fromList([3]));
      doc['list'].insert(1, Uint8List.fromList([2]));
    });
    expect(doc['list'].toList().length, equals(3));
    expect(doc['list'][0].toList(), equals([1]));
    expect(doc['list'][1].toList(), equals([2]));
    expect(doc['list'][2].toList(), equals([3]));
  });

  test('get and apply changes', () async {
    // Create Schema.
    Map<String, BaseType> schemaDescription = <String, BaseType>{
      'name': LastOneWinsString(),
      'number': Integer(),
      'cnt': IntCounter()
    };
    Schema schema = Schema(schemaDescription);

    // Create two Sledge documents
    Sledge sledgeA = newSledgeForTesting(), sledgeB = newSledgeForTesting();
    Document docA, docB;
    await sledgeA.runInTransaction(() async {
      docA = await sledgeA.getDocument(DocumentId(schema));
    });
    await sledgeB.runInTransaction(() async {
      docB = await sledgeB.getDocument(DocumentId(schema));
    });

    Change c1;
    await sledgeA.runInTransaction(() async {
      docA
        ..['name'].value = 'value + counter'
        ..['number'].value = 5
        ..['cnt'].add(1);

      c1 = docA.getChange();
    });

    docB.applyChange(c1);

    expect(docB['name'].value, equals('value + counter'));
    expect(docB['number'].value, equals(5));
    expect(docB['cnt'].value, equals(1));
  });

  test('put large list into set', () async {
    // Create Schema.
    Map<String, BaseType> schemaDescription = <String, BaseType>{
      'names': BytelistSet(),
    };
    Schema schema = Schema(schemaDescription);

    // Create two Sledge documents
    Sledge sledgeA = newSledgeForTesting(), sledgeB = newSledgeForTesting();
    Document docA, docB;
    await sledgeA.runInTransaction(() async {
      docA = await sledgeA.getDocument(DocumentId(schema));
    });
    await sledgeB.runInTransaction(() async {
      docB = await sledgeB.getDocument(DocumentId(schema));
    });

    final largeList = randomUint8List(10000);

    Change c1;
    await sledgeA.runInTransaction(() async {
      docA['names'].add(largeList);
      c1 = docA.getChange();
    });

    docB.applyChange(c1);
    expect(docB['names'].single, equals(largeList));
  });

  group('Rollback', () {
    test('rollback LastOneWinsValue', () async {
      // Create schemas.
      Map<String, BaseType> schemaDescription = <String, BaseType>{
        'someBool': Boolean(),
        'someInteger': Integer()
      };
      Schema schema = Schema(schemaDescription);

      // Create a new Sledge document.
      SledgeForTesting sledge = newSledgeForTesting();
      Document doc;
      await sledge.runInTransaction(() async {
        doc = await sledge.getDocument(DocumentId(schema));
      });
      // Read and write properties of a Sledge document.
      bool transactionSucceed = await sledge.runInTransaction(() async {
        doc['someInteger'].value = 14;
      });
      expect(transactionSucceed, true);
      expect(doc['someInteger'].value, equals(14));

      // Test case when transaction fails.
      transactionSucceed = await sledge.runInTransaction(() async {
        doc['someBool'].value = true;
        doc['someInteger'].value = 42;
        sledge.abortAndRollback();
      });
      expect(transactionSucceed, false);
      expect(doc['someBool'].value, equals(false));
      expect(doc['someInteger'].value, equals(14));

      // Check that after failed transaction we can get successful one.
      transactionSucceed = await sledge.runInTransaction(() async {
        doc['someInteger'].value = 8;
      });
      expect(transactionSucceed, true);
      expect(doc['someInteger'].value, equals(8));
    });

    test('rollback BytelistMap', () async {
      // Create schemas.
      Map<String, BaseType> schemaDescription = <String, BaseType>{
        'map': BytelistMap(),
      };
      Schema schema = Schema(schemaDescription);

      // Create a new Sledge document.
      SledgeForTesting sledge = newSledgeForTesting();
      Document doc;
      await sledge.runInTransaction(() async {
        doc = await sledge.getDocument(DocumentId(schema));
      });
      // Read and write properties of a Sledge document.
      bool transactionSucceed = await sledge.runInTransaction(() async {
        doc['map']['a'] = Uint8List.fromList([1, 2, 3]);
      });
      expect(transactionSucceed, true);
      expect(doc['map'].length, equals(1));

      // Test case when transaction fails.
      transactionSucceed = await sledge.runInTransaction(() async {
        doc['map']['a'] = Uint8List.fromList([4]);
        doc['map']['foo'] = Uint8List.fromList([1, 3]);
        sledge.abortAndRollback();
      });
      expect(transactionSucceed, false);
      expect(doc['map'].length, equals(1));
      expect(doc['map']['a'], equals([1, 2, 3]));

      transactionSucceed = await sledge.runInTransaction(() async {
        doc['map']['foo'] = Uint8List.fromList([1, 3]);
      });
      expect(transactionSucceed, true);
      expect(doc['map'].length, equals(2));
      expect(doc['map']['a'], equals([1, 2, 3]));
      expect(doc['map']['foo'], equals([1, 3]));

      transactionSucceed = await sledge.runInTransaction(() async {
        doc['map']['a'] = Uint8List.fromList([3, 4]);
      });
      expect(transactionSucceed, true);
      expect(doc['map']['a'], equals([3, 4]));
    });
  });
}
