// 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.

/// Since this file includes Sky/Mojo, it will need to be mocked out for unit
/// tests.
/// Unfortunately, imports can't be replaced, so the best thing to do is to swap
/// out the whole file.
///
/// The goal of the SettingsManager is to handle viewing and editing of the
/// Croupier Settings.
/// loadSettings: Get the settings of the current player or specified userID.
/// saveSettings: For the current player and their userID, save settings.
/// In the background, these values will be synced.
/// When setting up a syncgroup, the userIDs are very important.

import '../../logic/croupier_settings.dart' as util;
import 'croupier_client.dart' show CroupierClient;
import 'util.dart' as util;

import 'dart:async';
import 'dart:convert' show UTF8, JSON;

import 'package:ether/syncbase_client.dart' as sc;
import 'package:ether/src/naming/util.dart' as naming;

class SettingsManager {
  final util.updateCallbackT updateCallback;
  final CroupierClient _cc;

  sc.SyncbaseTable tb;
  sc.SyncbaseTable tbUser;

  SettingsManager([this.updateCallback]) : _cc = new CroupierClient();

  Future _prepareSettingsTable() async {
    if (tb != null && tbUser != null) {
      return; // Then we're already prepared.
    }

    sc.SyncbaseNoSqlDatabase db = await _cc.createDatabase();
    tb = await _cc.createTable(db, util.tableNameSettings);
    tbUser = await _cc.createTable(db, util.tableNameSettingsUser);

    // Start to watch the stream for the shared settings table.
    Stream<sc.WatchChange> watchStream =
        db.watch(util.tableNameSettings, '', await db.getResumeMarker());
    _startWatch(watchStream); // Don't wait for this future.
    _loadSettings(tb); // Don't wait for this future.

    // Don't wait for this future either.
    // TODO(alexfandrianto): This is a way to debug who is present in the syncgroup.
    // This should be removed in the near future, once we are more certain about
    // the syncgroups we have formed.
    _joinOrCreateSyncgroup().then((var sg) {
      new Timer.periodic(const Duration(seconds: 3), (Timer _) async {
        Map<String, sc.SyncgroupMemberInfo> members = await sg.getMembers();
        print("There are ${members.length} members.");
        print(members);
      });
    });
  }

  Future<String> load([int userID]) async {
    util.log('SettingsManager.load');
    await _prepareSettingsTable();

    if (userID == null) {
      return _tryReadData(tbUser, "settings");
    }
    return _tryReadData(tb, "${userID}");
  }

  Future<String> _tryReadData(sc.SyncbaseTable st, String rowkey) async {
    var row = st.row(rowkey);
    if (!(await row.exists())) {
      print("${rowkey} did not exist");
      return null;
    }
    return UTF8.decode(await row.get());
  }

  // Since only the current user is allowed to save, we should also save to the
  // user's personal settings as well.
  Future save(int userID, String jsonString) async {
    util.log('SettingsManager.save');
    await _prepareSettingsTable();

    await tbUser.row("settings").put(UTF8.encode(jsonString));
    await tb.row("${userID}").put(UTF8.encode(jsonString));
  }

  // This watch method ensures that any changes are propagated to the caller.
  // In the case of the settings manager, we're checking for any changes to
  // any person's Croupier Settings.
  Future _startWatch(Stream<sc.WatchChange> watchStream) async {
    util.log('Settings watching for changes...');
    // This stream never really ends, so I guess we'll watch forever.
    await for (sc.WatchChange wc in watchStream) {
      assert(wc.tableName == util.tableNameSettings);
      util.log('Watch Key: ${wc.rowKey}');
      util.log('Watch Value ${UTF8.decode(wc.valueBytes)}');
      String key = wc.rowKey;
      String value;
      switch (wc.changeType) {
        case sc.WatchChangeTypes.put:
          value = UTF8.decode(wc.valueBytes);
          break;
        case sc.WatchChangeTypes.delete:
          value = null;
          break;
        default:
          assert(false);
      }

      if (this.updateCallback != null) {
        this.updateCallback(key, value);
      }
    }
  }

  // When starting the settings manager, there may be settings already in the
  // store. Make sure to load those.
  Future _loadSettings(sc.SyncbaseTable tb) async {
    tb.scan(new sc.RowRange.prefix('')).forEach((sc.KeyValue kv) {
      this.updateCallback(kv.key, UTF8.decode(kv.value));
    });
  }


  Future<sc.SyncbaseSyncgroup> _joinOrCreateSyncgroup() async {

    sc.SyncbaseNoSqlDatabase db = await _cc.createDatabase();
    String mtAddr = util.mtAddr;
    String tableName = util.tableNameSettings;

    var mtName = mtAddr;
    var sgPrefix = naming.join(mtName, util.sgPrefix);
    var sgName = naming.join(sgPrefix, util.sgName);
    var sg = db.syncgroup(sgName);

    print('SGNAME = $sgName');

    var myInfo = sc.SyncbaseClient.syncgroupMemberInfo(syncPriority: 3);

    try {
      print('trying to join syncgroup');
      await sg.join(myInfo);
      print('syncgroup join success');
    } catch (e) {
      // Syncgroup does not exist.
      print('syncgroup does not exist, creating it');

      var sgSpec = sc.SyncbaseClient.syncgroupSpec(
          // Sync the entire table.
          [sc.SyncbaseClient.syncgroupPrefix(tableName, '')],
          description: 'test syncgroup',
          perms: util.openPerms,
          mountTables: [mtName]);

      print('SGSPEC = $sgSpec');

      await sg.create(sgSpec, myInfo);
      print('syncgroup create success');
    }

    return sg;
  }

}
