// Copyright 2015 The Vanadium 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 'dart:convert' show JSON;

enum SimulLevel { turnBased, independent, dependent }

typedef void KeyValueCallback(String key, String value);

class LogWriter {
  LogWriter(this.updateCallback, this.users);

  final KeyValueCallback updateCallback;
  final List<int> users;
  String logPrefix; // This can be completely ignored.

  bool inProposalMode = false;
  int associatedUser;

  int _fakeTime = 0;
  int _getNextTime() {
    _fakeTime++;
    return _fakeTime;
  }

  Map<String, String> _data = new Map<String, String>();

  Future onChange(String rowKey, String value, bool duringScan) async {}

  void write(SimulLevel s, String value) {
    assert(!inProposalMode);

    String key = _logKey(associatedUser);
    if (s == SimulLevel.dependent) {
      // We have to do extra work with "proposals".
      inProposalMode = true;
      String proposalData = JSON.encode({"key": key, "value": value});
      _data[_proposalKey(associatedUser)] = proposalData;

      // FAKE: Do some bonus work. Where "everyone else" accepts the proposal.
      for (int i = 0; i < users.length; i++) {
        if (users[i] != associatedUser) {
          _data[_proposalKey(users[i])] = proposalData;
          _receiveProposal(proposalData);
        }
      }

      return;
    }

    _writeData(key, value);
  }

  // Helper that returns the log key using a mixture of timestamp + user.
  String _logKey(int user) {
    int ms = _getNextTime();
    String key = "$ms-$user";
    return key;
  }

  // Helper that writes data to the "store" and calls the update callback.
  void _writeData(String key, String value) {
    _data[key] = value;
    updateCallback(key, value);
  }

  // Helper that handles a proposal update for a user.
  void _receiveProposal(String proposalData) {
    assert(inProposalMode);

    // First check if something is already in data.
    var pKey = _proposalKey(associatedUser);
    String pData = _data[pKey];
    if (pData != null) {
      // Potentially change your proposal, if that person has higher priority.
      Map<String, String> pp = JSON.decode(pData);
      Map<String, String> op = JSON.decode(proposalData);
      String keyP = pp["key"];
      String keyO = op["key"];
      if (keyO.compareTo(keyP) < 0) {
        // Then switch proposals.
        _data[pKey] = proposalData;
      }
    } else {
      // Otherwise, you have no proposal, so take theirs.
      _data[pKey] = proposalData;
    }

    // Given these changes, check if you can commit the full batch.
    if (_checkIsProposalDone()) {
      Map<String, String> pp = JSON.decode(pData);
      String key = pp["key"];
      String value = pp["value"];

      // WOULD DO A BATCH!
      _writeData(key, value);
      for (int i = 0; i < users.length; i++) {
        _data.remove(_proposalKey(users[i]));
      }

      inProposalMode = false;
    }
  }

  // More helpers for proposals.
  String _proposalKey(int user) {
    return "proposal$user";
  }

  bool _checkIsProposalDone() {
    assert(inProposalMode);
    String theProposal;
    for (int i = 0; i < users.length; i++) {
      String altProposal = _data[_proposalKey(users[i])];
      if (altProposal == null) {
        return false;
      } else if (theProposal != null && theProposal != altProposal) {
        return false;
      }
      theProposal = altProposal;
    }
    return true;
  }
}
