// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. 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:observable/observable.dart';
import 'package:test/test.dart';

main() {
  group('$ObservableList', () {
    group('list api', _runListTests);
    _runObservableListTests();
    _runDeprecatedTests();
  });
}

bool _hasListChanges(List<ChangeRecord> c) {
  return c.any((r) => r is ListChangeRecord);
}

bool _hasPropChanges(List<ChangeRecord> c) {
  return c.any((r) => r is PropertyChangeRecord);
}

bool _onlyListChanges(ChangeRecord c) => c is ListChangeRecord;

bool _onlyPropRecords(ChangeRecord c) => c is PropertyChangeRecord;

_runListTests() {
  // TODO(matanl): Can we run the List-API tests from the SDK?
  // Any methods actually implemented by ObservableList are below, otherwise I
  // am relying on the test suite for DelegatingList.
  test('index set operator', () {
    final list = new ObservableList<String>(1)..[0] = 'value';
    expect(list, ['value']);
  });

  test('add', () {
    final list = new ObservableList<String>()..add('value');
    expect(list, ['value']);
  });

  test('addAll', () {
    final list = new ObservableList<String>()..addAll(['a', 'b', 'c']);
    expect(list, ['a', 'b', 'c']);
  });

  test('clear', () {
    final list = new ObservableList<String>.from(['a', 'b', 'c'])..clear();
    expect(list, isEmpty);
  });

  test('fillRange', () {
    final list = new ObservableList<String>(5)..fillRange(0, 5, 'a');
    expect(list, ['a', 'a', 'a', 'a', 'a']);
  });

  test('insert', () {
    final list = new ObservableList<String>.from(['a', 'c'])..insert(1, 'b');
    expect(list, ['a', 'b', 'c']);
  });

  test('insertAll', () {
    final list = new ObservableList<String>.from(['c']);
    list.insertAll(0, ['a', 'b']);
    expect(list, ['a', 'b', 'c']);
  });

  test('length', () {
    final list = new ObservableList<String>()..length = 3;
    expect(list, [null, null, null]);
    list.length = 1;
    expect(list, [null]);
    list.length = 0;
    expect(list, isEmpty);
  });

  test('remove', () {
    final list = new ObservableList<String>.from(['a', 'b', 'c']);
    expect(list.remove('b'), isTrue);
    expect(list, ['a', 'c']);
  });

  test('removeAt', () {
    final list = new ObservableList<String>.from(['a', 'b', 'c']);
    expect(list.removeAt(1), 'b');
    expect(list, ['a', 'c']);
  });

  test('removeLast', () {
    final list = new ObservableList<String>.from(['a', 'b', 'c']);
    expect(list.removeLast(), 'c');
  });

  test('removeRange', () {
    final list = new ObservableList<String>.from(['a', 'b', 'c']);
    list.removeRange(0, 2);
    expect(list, ['c']);
  });

  test('removeWhere', () {
    final list = new ObservableList<String>.from(['a', 'b', 'a', 'b']);
    list.removeWhere((v) => v == 'a');
    expect(list, ['b', 'b']);
  });

  test('retainWhere', () {
    final list = new ObservableList<String>.from(['a', 'b', 'a', 'b']);
    list.retainWhere((v) => v == 'a');
    expect(list, ['a', 'a']);
  });

  test('setAll', () {
    final list = new ObservableList<String>.from(['a', 'b', 'c']);
    list.setAll(1, ['d', 'f']);
    expect(list, ['a', 'd', 'f']);
  });

  test('setRange', () {
    final list = new ObservableList<String>.from(['a', 'b', 'c']);
    list.setRange(0, 2, ['d', 'e']);
    expect(list, ['d', 'e', 'c']);
    list.setRange(1, 3, ['f', 'g', 'h'], 1);
    expect(list, ['d', 'g', 'h']);
  });
}

// These are the tests we will keep after deprecations occur.
_runObservableListTests() {
  group('content changes', () {
    Completer<List<ChangeRecord>> completer;
    List<String> previousState;

    ObservableList<String> list;
    Stream<List<ChangeRecord>> stream;
    StreamSubscription sub;

    Future next() {
      completer = new Completer<List<ListChangeRecord>>.sync();
      return completer.future;
    }

    Future<Null> expectChanges(List<ListChangeRecord> changes) {
      // Applying these change records in order should make the new list.
      for (final change in changes) {
        change.apply(previousState);
      }
      expect(list, previousState);

      // If these fail, it might be safe to update if optimized/changed.
      return next().then((actualChanges) {
        expect(actualChanges, changes);
      });
    }

    setUp(() {
      previousState = ['a', 'b', 'c'];
      list = new ObservableList<String>.from(previousState);
      stream = list.changes.where(_hasListChanges);
      sub = stream.listen((c) {
        if (completer?.isCompleted == false) {
          completer.complete(c.where(_onlyListChanges).toList());
        }
        previousState = list.toList();
      });
    });

    tearDown(() => sub.cancel());

    ListChangeRecord _delta(
      int index, {
      List removed: const [],
      int addedCount: 0,
    }) {
      return new ListChangeRecord(
        list,
        index,
        removed: removed,
        addedCount: addedCount,
      );
    }

    test('operator[]=', () async {
      list[0] = 'd';
      await expectChanges([
        _delta(0, removed: ['a'], addedCount: 1),
      ]);
    });

    test('add', () async {
      list.add('d');
      await expectChanges([
        _delta(3, addedCount: 1),
      ]);
    });

    test('addAll', () async {
      list.addAll(['d', 'e']);
      await expectChanges([
        _delta(3, addedCount: 2),
      ]);
    });

    test('clear', () async {
      list.clear();
      await expectChanges([
        _delta(0, removed: ['a', 'b', 'c']),
      ]);
    });

    test('fillRange', () async {
      list.fillRange(1, 3, 'd');
      await expectChanges([
        _delta(1, removed: ['b', 'c'], addedCount: 2),
      ]);
    });

    test('insert', () async {
      list.insert(1, 'd');
      await expectChanges([
        _delta(1, addedCount: 1),
      ]);
    });

    test('insertAll', () async {
      list.insertAll(1, ['d', 'e']);
      await expectChanges([
        _delta(1, addedCount: 2),
      ]);
    });

    test('length', () async {
      list.length = 5;
      await expectChanges([
        _delta(3, addedCount: 2),
      ]);
      list.length = 1;
      await expectChanges([
        _delta(1, removed: ['b', 'c', null, null])
      ]);
    });

    test('remove', () async {
      list.remove('b');
      await expectChanges([
        _delta(1, removed: ['b'])
      ]);
    });

    test('removeAt', () async {
      list.removeAt(1);
      await expectChanges([
        _delta(1, removed: ['b'])
      ]);
    });

    test('removeRange', () async {
      list.removeRange(0, 2);
      await expectChanges([
        _delta(0, removed: ['a', 'b'])
      ]);
    });

    test('removeWhere', () async {
      list.removeWhere((s) => s == 'b');
      await expectChanges([
        _delta(1, removed: ['b'])
      ]);
    });

    test('replaceRange', () async {
      list.replaceRange(0, 2, ['d', 'e']);
      await expectChanges([
        // Normally would be
        //   _delta(0, removed: ['a', 'b']),
        //   _delta(0, addedCount: 2),
        // But projectListSplices(...) optimizes to single record
        _delta(0, removed: ['a', 'b'], addedCount: 2),
      ]);
    });

    test('retainWhere', () async {
      list.retainWhere((s) => s == 'b');
      await expectChanges([
        _delta(0, removed: ['a']),
        _delta(1, removed: ['c']),
      ]);
    });

    test('setAll', () async {
      list.setAll(1, ['d', 'e']);
      await expectChanges([
        _delta(1, removed: ['b', 'c'], addedCount: 2),
      ]);
    });

    test('setRange', () async {
      list.setRange(0, 2, ['d', 'e']);
      await expectChanges([
        _delta(0, removed: ['a', 'b'], addedCount: 2),
      ]);
      list.setRange(1, 3, ['f', 'g', 'h'], 1);
      await expectChanges([
        _delta(1, removed: ['e', 'c'], addedCount: 2),
      ]);
    });
  });
}

// These are tests we will remove after deprecations occur.
_runDeprecatedTests() {
  group('listChanges stream', () {
    Completer<List<ListChangeRecord>> completer;
    ObservableList<String> list;
    List<String> previousState;
    StreamSubscription sub;

    Future next() {
      completer = new Completer<List<ListChangeRecord>>.sync();
      return completer.future;
    }

    Future<Null> expectChanges(List<ListChangeRecord> changes) {
      // Applying these change records in order should make the new list.
      for (final change in changes) {
        change.apply(previousState);
      }
      expect(list, previousState);

      // If these fail, it might be safe to update if optimized/changed.
      return next().then((actualChanges) {
        expect(actualChanges, changes);
      });
    }

    setUp(() {
      previousState = ['a', 'b', 'c'];
      list = new ObservableList<String>.from(previousState);
      sub = list.listChanges.listen((c) {
        if (completer?.isCompleted == false) {
          completer.complete(c.toList());
        }
        previousState = list.toList();
      });
    });

    tearDown(() => sub.cancel());

    test('updates when an index changes', () async {
      list[0] = 'd';
      await expectChanges([
        new ListChangeRecord.replace(list, 0, ['a']),
      ]);
    });

    test('should not emit an empty list', () async {
      // This is optimized into a no-op.
      list[0] = 'd';
      list[0] = 'a';
      next().then((_) {
        fail('Should not emit change records');
      });
      await new Future.value();
    });
  });

  group('length changes', () {
    Completer<List<ChangeRecord>> completer;
    ObservableList<String> list;
    Stream<List<ChangeRecord>> stream;
    StreamSubscription sub;

    Future next() {
      completer = new Completer<List<ListChangeRecord>>.sync();
      return completer.future;
    }

    setUp(() {
      list = new ObservableList<String>.from(['a', 'b', 'c']);
      stream = list.changes.where(_hasPropChanges);
      sub = stream.listen((c) {
        if (completer?.isCompleted == false) {
          completer.complete(c.where(_onlyPropRecords).toList());
        }
      });
    });

    tearDown(() => sub.cancel());

    PropertyChangeRecord _length(int oldLength, int newLength) {
      return new PropertyChangeRecord(list, #length, oldLength, newLength);
    }

    PropertyChangeRecord _isEmpty(bool oldValue, bool newValue) {
      return new PropertyChangeRecord(list, #isEmpty, oldValue, newValue);
    }

    PropertyChangeRecord _isNotEmpty(bool oldValue, bool newValue) {
      return new PropertyChangeRecord(list, #isNotEmpty, oldValue, newValue);
    }

    test('add', () async {
      list.add('d');
      expect(await next(), [
        _length(3, 4),
      ]);
    });

    test('addAll', () async {
      list.addAll(['d', 'e']);
      expect(await next(), [
        _length(3, 5),
      ]);
    });

    test('clear', () async {
      list.clear();
      expect(await next(), [
        _length(3, 0),
        _isEmpty(false, true),
        _isNotEmpty(true, false),
      ]);
    });

    test('insert', () async {
      list.insert(0, 'd');
      expect(await next(), [
        _length(3, 4),
      ]);
    });

    test('insertAll', () async {
      list.insertAll(0, ['d', 'e']);
      expect(await next(), [
        _length(3, 5),
      ]);
    });

    test('length', () async {
      list.length = 5;
      expect(await next(), [
        _length(3, 5),
      ]);

      list.length = 0;
      expect(await next(), [
        _length(5, 0),
        _isEmpty(false, true),
        _isNotEmpty(true, false),
      ]);

      list.length = 1;
      expect(await next(), [
        _length(0, 1),
        _isEmpty(true, false),
        _isNotEmpty(false, true),
      ]);
    });

    test('remove', () async {
      list.remove('a');
      expect(await next(), [
        _length(3, 2),
      ]);
    });

    test('removeAt', () async {
      list.removeAt(0);
      expect(await next(), [
        _length(3, 2),
      ]);
    });

    test('removeLast', () async {
      list.removeLast();
      expect(await next(), [
        _length(3, 2),
      ]);
    });

    test('removeRange', () async {
      list.removeRange(0, 2);
      expect(await next(), [
        _length(3, 1),
      ]);
    });

    test('removeWhere', () async {
      list.removeWhere((s) => s == 'a');
      expect(await next(), [
        _length(3, 2),
      ]);
    });

    test('retainWhere', () async {
      list.retainWhere((s) => s == 'a');
      expect(await next(), [
        _length(3, 1),
      ]);
    });
  });
}
