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

import 'package:sledge/sledge.dart';

import 'checker.dart';
import 'node.dart';
import 'storage_state.dart';

// FleetState stores states of group of instances and associated with them
// StorageStates. It allows to perform modification on one instance, or to
// synchronize states of two instances.
//
// TODO: consider removing dynamic
class FleetState<T extends dynamic> {
  // ignore: unused_field
  int _fleetSize;
  final List<StorageState> _storageStates;
  final List<T> _instances;
  final List<Checker<T>> _checkers = <Checker<T>>[];

  FleetState(int size, T instanceGenerator(int index))
      : _fleetSize = size,
        _storageStates = new List<StorageState>.generate(
            size, (index) => new StorageState(),
            growable: false),
        _instances =
            new List<T>.generate(size, instanceGenerator, growable: false) {
    for (int i = 0; i < size; i++) {
      if (T == Sledge) {
        _storageStates[i] = _instances[i].fakeLedgerPage.storageState;
      } else if (T == Document) {
        _storageStates[i] = new StorageState(
            (change) => _instances.cast<Document>()[i].applyChange(change));
      } else {
        _storageStates[i] = new StorageState(_instances[i].applyChange);
      }
    }
  }

  Future applyNode(Node node, int timer) async {
    if (node is ModificationNode<T>) {
      await applyModification(node.instanceId, node.modification, timer);
    } else if (node is SynchronizationNode) {
      applySynchronization(node.instanceId1, node.instanceId2);
    }

    for (final checker in _checkers) {
      for (final instanceId in node.affectedInstances) {
        checker.check(_instances[instanceId]);
      }
    }
  }

  void addChecker(Checker<T> checker) {
    _checkers.add(checker);
  }

  Future applyModification(
      int id, Future Function(T) modification, int time) async {
    if (T == Sledge) {
      await _instances[id].runInTransaction(() => modification(_instances[id]));
    } else {
      await modification(_instances[id]);
      if (T == Document) {
        _storageStates[id]
            .applyChange(_instances.cast<Document>()[id].getChange(), time);
        _instances.cast<Document>()[id].completeTransaction();
      } else {
        _storageStates[id].applyChange(_instances[id].getChange(), time);
        _instances[id].completeTransaction();
      }
    }
  }

  void applySynchronization(int id1, int id2) {
    _storageStates[id1].updateWith(_storageStates[id2]);
    _storageStates[id2].updateWith(_storageStates[id1]);
  }
}
