// 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 'package:sledge/src/document/leaf_value.dart'; // ignore: implementation_imports
import 'package:test/test.dart';

import '../dummies/dummy_value_observer.dart';

// TODO: make tests generic.
// typedef SetCreator = Set<K, V> Function<K, V>();
// issue: template arguments of generic function have dynamic runtime type, so
// Converter factory constructor throws exception.
typedef SetCreator = Set<int> Function();

/// Generic class, to test if [TestingSet] correctly implements Set API.
class SetApiTester<TestingSet extends Set> {
  SetCreator _setCreator;

  SetApiTester(this._setCreator);

  /// Tests Set API implementation.
  void testApi() {
    test('iterator', () {
      final s = _setCreator()..addAll([1, 3, 4]);
      final it = s.iterator;
      final list = <int>[];
      while (it.moveNext()) {
        list.add(it.current);
      }
      expect(list, equals([1, 3, 4]));
    });

    test('first', () {
      final s = _setCreator();
      expect(() => s.first, throwsStateError);
      s.add(1);
      expect(s.first, equals(1));
    });

    test('hashCode', () {
      // ignore: unused_local_variable
      final s = _setCreator().hashCode;
    });

    test('isEmpty', () {
      final s = _setCreator();
      expect(s.isEmpty, isTrue);
      s.add(1);
      expect(s.isEmpty, isFalse);
    });

    test('isNotEmpty', () {
      final s = _setCreator();
      expect(s.isNotEmpty, isFalse);
      s.add(1);
      expect(s.isNotEmpty, isTrue);
    });

    test('last', () {
      final s = _setCreator();
      expect(() => s.last, throwsStateError);
      s.add(1);
      expect(s.last, equals(1));
      s.add(2);
      expect(s.last, isNot(equals(s.first)));
    });

    test('length', () {
      final s = _setCreator();
      expect(s.length, equals(0));
      s..add(0)..add(2)..add(4)..add(4);
      expect(s.length, equals(3));
    });

    test('single', () {
      final s = _setCreator();
      expect(() => s.single, throwsStateError);
      s.add(1);
      expect(s.single, equals(1));
      s.add(2);
      expect(() => s.single, throwsStateError);
    });

    test('operator ==', () {
      final s = _setCreator();
      expect(s == s, isTrue);
      final otherStorage = _setCreator();
      expect(s == otherStorage, isFalse);
    });

    test('add()', () {
      final s = _setCreator();
      expect(s.add(1), isTrue);
      expect(s.add(1), isFalse);
      expect(s.add(2), isTrue);
      expect(s.contains(1), isTrue);
      expect(s.contains(2), isTrue);
    });

    test('addAll()', () {
      final s = _setCreator()..add(0)..add(2)..add(4);
      final other = _setCreator()..add(0)..add(1);
      s.addAll(other);

      expect(s.toList()..sort(), equals([0, 1, 2, 4]));
    });

    test('clear()', () {
      final s = _setCreator()
        ..add(0)
        ..add(2)
        ..add(4)
        ..clear();
      expect(s.isEmpty, isTrue);
    });

    test('contains()', () {
      final s = _setCreator();
      expect(s.contains(0), isFalse);
      expect(s.contains(1), isFalse);
      s.add(0);
      expect(s.contains(0), isTrue);
      expect(s.contains(1), isFalse);
    });

    test('containsAll()', () {
      final s = _setCreator();
      expect(s.containsAll([]), isTrue);
      expect(s.containsAll([0, 1]), isFalse);
      s.add(0);
      expect(s.containsAll([0, 1]), isFalse);
      expect(s.containsAll([0, 0]), isTrue);
      s.add(1);
      expect(s.containsAll([0, 1]), isTrue);
      expect(s.containsAll([0, 2]), isFalse);
      expect(s.containsAll([1]), isTrue);
    });

    test('difference()', () {
      final s = _setCreator()..addAll([1, 2, 3]);
      final other = _setCreator()..addAll([2, 4]);
      final diff = s.difference(other);
      expect(diff.length, equals(2));
      expect(diff.containsAll([1, 3]), isTrue);
    });

    test('intersection()', () {
      final s = _setCreator()..addAll([1, 2, 3]);
      final other = _setCreator()..addAll([2, 3, 4]);
      final inter = s.intersection(other);
      expect(inter.length, equals(2));
      expect(inter.containsAll([2, 3]), isTrue);
    });

    test('lookup()', () {
      final s = _setCreator()..addAll([1, 2, 3]);
      expect(s.lookup(0), equals(null));
      expect(s.lookup(1), equals(1));
      expect(s.lookup(2), equals(2));
      expect(s.lookup(3), equals(3));
    });

    test('remove()', () {
      final s = _setCreator()..addAll([1, 2, 3]);
      expect(s.remove(1), isTrue);
      expect(s.toList()..sort(), equals([2, 3]));
      expect(s.remove(3), isTrue);
      expect(s.toList()..sort(), equals([2]));
      expect(s.remove(1), isFalse);
      expect(s.remove(3), isFalse);
      expect(s.remove(2), isTrue);
      expect(s.isEmpty, isTrue);
    });

    test('removeAll()', () {
      final s = _setCreator()
        ..addAll([1, 2, 3])
        ..removeAll([1, 3]);
      expect(s.toList(), equals([2]));
      s
        ..addAll([1, 2, 3, 4, 5])
        ..removeAll([2, 4, 6, 5, 10, 20]);
      expect(s.toList()..sort(), equals([1, 3]));
      s.removeAll([1, 2, 3, 4, 5]);
      expect(s.isEmpty, true);
    });

    test('removeWhere()', () {
      final s = _setCreator()
        ..addAll([1, 2, 3, 4, 5, 6])
        ..removeWhere((x) => x.isEven);
      expect(s.toList()..sort(), equals([1, 3, 5]));
      s
        ..addAll([1, 2, 3, 4, 5, 6])
        ..removeWhere((x) => true);
      expect(s.isEmpty, isTrue);
    });

    test('retainWhere()', () {
      final s = _setCreator()
        ..addAll([1, 2, 3, 4, 5, 6])
        ..retainWhere((x) => x.isEven);
      expect(s.toList()..sort(), equals([2, 4, 6]));
      s
        ..addAll([1, 2, 3, 4, 5, 6])
        ..retainWhere((x) => false);
      expect(s.isEmpty, isTrue);
    });

    test('toSet()', () {
      final s = _setCreator()
        ..addAll([1, 2, 3, 4, 5])
        ..remove(2);
      expect(s.toSet().toList()..sort(), equals([1, 3, 4, 5]));
    });

    // TODO: add tests for inherited methods.
  }

  void testObserver() {
    test('Observer calls.', () {
      final s = _setCreator();
      final observer = new DummyValueObserver();
      expect(s, const TypeMatcher<LeafValue>());
      dynamic leafValue = s;
      leafValue.observer = observer; // ignore: cascade_invocations
      expect(s.contains(0), equals(false));
      observer.expectNotChanged();

      // Check that each modification method calls observer.valueWasChanged():
      s.add(2);
      observer
        ..expectChanged()
        ..reset();

      s.addAll([1, 2, 3, 4, 5]);
      observer
        ..expectChanged()
        ..reset();

      s.remove(1);
      observer
        ..expectChanged()
        ..reset();

      s.removeAll([1, 2]);
      observer
        ..expectChanged()
        ..reset();

      s.removeWhere((x) => x.isEven);
      observer
        ..expectChanged()
        ..reset();

      s.retainWhere((x) => x == 3);
      observer
        ..expectChanged()
        ..reset();

      s.clear();
      observer
        ..expectChanged()
        ..reset();
    });
  }
}
