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

part of syncbase_store;

class _AppActions extends AppActions {
  _AppState _state;
  Function _emitChange;
  _AppActions(this._state, this._emitChange);

  //////////////////////////////////////
  // Decks

  Future addDeck(model.Deck deck) async {
    log.info("Adding deck ${deck.name}...");
    sb.SyncbaseTable tb = _getDecksTable();
    await tb.put(deck.key, UTF8.encode(deck.toJson()));
    log.info("Deck ${deck.name} added.");
  }

  Future removeDeck(String deckKey) async {
    sb.SyncbaseTable tb = _getDecksTable();
    tb.deleteRange(new sb.RowRange.prefix(deckKey));
  }

  Future setSlides(String deckKey, List<model.Slide> slides) async {
    sb.SyncbaseTable tb = _getDecksTable();

    slides.forEach((slide) async {
      // TODO(aghassemi): Use batching.
      await tb.put(
          keyutil.getSlideKey(deckKey, slide.num), UTF8.encode(slide.toJson()));
    });
  }

  Future setCurrSlideNum(String deckId, int slideNum) async {
    var deckState = _state._getOrCreateDeckState(deckId);
    if (slideNum < 0 || slideNum >= deckState.slides.length) {
      throw new ArgumentError.value(slideNum,
          "Slide number out of range. Only ${deckState.slides.length} slides exist.");
    }

    // TODO(aghassemi): Have a session table to persist UI state such as
    // local slide number within a deck, whether user is navigating a presentation
    // on their own, and similar UI state that is desirable to be persisted.
    deckState._currSlideNum = slideNum;

    // Is slide number change happening within a presentation?
    if (deckState.presentation != null) {
      // Is the current user driving the presentation?
      if (deckState.presentation.isDriving(_state.user)) {
        // Update the common slide number for the presentation.
        sb.SyncbaseTable tb = _getPresentationsTable();
        await tb.put(
            keyutil.getPresentationCurrSlideNumKey(
                deckId, deckState.presentation.key),
            UTF8.encode(slideNum.toString()));
      } else {
        // User is not driving the presentation so they are navigating on their own.
        deckState.presentation._isFollowingPresentation = false;
      }
    }
    _emitChange();
  }

  Future loadDeckFromSdCard() {
    return new Loader.singleton().loadDeck();
  }

  //////////////////////////////////////
  // Presentation

  Future<model.PresentationAdvertisement> startPresentation(
      String deckId) async {
    if (!_state._decks.containsKey(deckId)) {
      throw new ArgumentError.value(deckId, 'Deck no longer exists.');
    }

    // Stop the existing presentation, if any.
    if (_state._advertisedPresentation != null) {
      await stopPresentation(_state._advertisedPresentation.key);
    }

    model.Deck deck = _state._getOrCreateDeckState(deckId)._deck;
    String presentationId = uuidutil.createUuid();
    String syncgroupName = _getSyncgroupName(_state.settings, presentationId);
    String thumbnailSyncgroupName =
        _getSyncgroupName(_state.settings, deck.thumbnail.key);

    var presentation = new model.PresentationAdvertisement(
        presentationId, deck, syncgroupName, thumbnailSyncgroupName);

    // Syncgroup for deck and presentation data, including blobs.
    await sb.createSyncgroup(_state.settings.mounttable, syncgroupName, [
      sb.SyncbaseClient.syncgroupPrefix(decksTableName, deckId),
      sb.SyncbaseClient.syncgroupPrefix(presentationsTableName,
          keyutil.getPresentationPrefix(deckId, presentationId)),
      sb.SyncbaseClient.syncgroupPrefix(blobsTableName, deckId)
    ]);

    // TODO(aghassemi): Use a simple RPC instead of a syncgroup to get the thumbnail.
    // See https://github.com/vanadium/syncslides/issues/17
    // Syncgroup for deck thumbnail.
    await sb.createSyncgroup(
        _state.settings.mounttable, thumbnailSyncgroupName, [
      sb.SyncbaseClient.syncgroupPrefix(blobsTableName, deck.thumbnail.key)
    ]);

    await discovery.advertise(presentation);
    _state._advertisedPresentation = presentation;

    // Set the presentation state for the deck.
    _DeckState deckState = _state._getOrCreateDeckState(deckId);
    _PresentationState presentationstate =
        deckState._getOrCreatePresentationState(presentation.key);
    presentationstate._isOwner = true;

    setDefaultsAndJoin() async {
      // Set the current slide number to 0.
      sb.SyncbaseTable tb = _getPresentationsTable();
      await tb.put(
          keyutil.getPresentationCurrSlideNumKey(deckId, presentation.key),
          UTF8.encode('0'));

      // Set the current user as the driver.
      await _setPresentationDriver(deckId, presentation.key, _state.user);

      // Also join the presentation.
      await joinPresentation(presentation);
    }

    try {
      // Wait for join. If it fails, remove the presentation state from the deck.
      await setDefaultsAndJoin();
    } catch (e) {
      deckState._isPresenting = false;
      throw e;
    }

    return presentation;
  }

  Future joinPresentation(model.PresentationAdvertisement presentation) async {
    String deckId = presentation.deck.key;

    // Set the presentation state for the deck.
    _DeckState deckState = _state._getOrCreateDeckState(deckId);
    deckState._getOrCreatePresentationState(presentation.key);

    deckState._isPresenting = true;

    // Wait until at least the current slide number, driver and the slide for current slide number is synced.
    join() async {
      bool isMyOwnPresentation =
          _state._advertisedPresentation?.key == presentation.key;
      if (!isMyOwnPresentation) {
        await sb.joinSyncgroup(presentation.syncgroupName);
      }

      Completer completer = new Completer();
      new Timer.periodic(new Duration(milliseconds: 30), (Timer timer) {
        if (_state._decks.containsKey(deckId) &&
            _state._decks[deckId].deck != null &&
            _state._decks[deckId].presentation != null &&
            _state._decks[deckId].slides.length >
                _state._decks[deckId].presentation.currSlideNum &&
            _state._decks[deckId].presentation.driver != null &&
            !completer.isCompleted) {
          timer.cancel();
          completer.complete();
        }
      });
      await completer.future.timeout(new Duration(seconds: 20));
    }

    try {
      // Wait for join. If it fails, remove the presentation state from the deck.
      await join();
    } catch (e) {
      deckState._isPresenting = false;
      throw e;
    }

    log.info('Joined presentation ${presentation.key}');
  }

  Future stopPresentation(String presentationId) async {
    await discovery.stopAdvertising(presentationId);
    _state._advertisedPresentation = null;
    _state._decks.values.forEach((_DeckState deck) {
      if (deck.presentation != null &&
          deck.presentation.key == presentationId) {
        deck._isPresenting = false;
      }
    });
    _emitChange();
    log.info('Presentation $presentationId stopped');
  }

  Future followPresentation(String deckId) async {
    var deckState = _state._getOrCreateDeckState(deckId);

    if (deckState.presentation == null) {
      throw new ArgumentError.value(deckId, 'Deck is not being presented.');
    }

    // Set the current slide number to the presentation's current slide number.
    await setCurrSlideNum(deckId, deckState.presentation.currSlideNum);

    deckState.presentation._isFollowingPresentation = true;
  }

  Future askQuestion(String deckId, int slideNum, String questionText) async {
    var deckState = _state._getOrCreateDeckState(deckId);

    if (deckState.presentation == null) {
      throw new ArgumentError.value(deckId,
          'Cannot ask a question because deck is not part of a presentation');
    }

    sb.SyncbaseTable tb = _getPresentationsTable();
    String questionId = uuidutil.createUuid();

    model.Question question = new model.Question(
        questionId, questionText, slideNum, _state.user, new DateTime.now());

    var key = keyutil.getPresentationQuestionKey(
        deckId, deckState.presentation.key, questionId);

    await tb.put(key, UTF8.encode(question.toJson()));
  }

  Future setDriver(String deckId, model.User driver) async {
    var deckState = _state._getOrCreateDeckState(deckId);

    if (deckState.presentation == null) {
      throw new ArgumentError.value(deckId,
          'Cannot set the driver because deck is not part of a presentation');
    }
    await _setPresentationDriver(deckId, deckState.presentation.key, driver);
  }

  //////////////////////////////////////
  // Blobs

  Future putBlob(String key, List<int> bytes) async {
    sb.SyncbaseTable tb = _getBlobsTable();
    await tb.put(key, bytes);
  }

  Future<List<int>> getBlob(String key) async {
    sb.SyncbaseTable tb = _getBlobsTable();
    return tb.get(key);
  }
}

//////////////////////////////////////
// Utilities

Future _setPresentationDriver(
    String deckId, String presentationId, model.User driver) async {
  sb.SyncbaseTable tb = _getPresentationsTable();
  await tb.put(keyutil.getPresentationDriverKey(deckId, presentationId),
      UTF8.encode(driver.toJson()));
}

String _getSyncgroupName(model.Settings settings, String uuid) {
  return '${settings.mounttable}/${settings.deviceId}/%%sync/$uuid';
}

sb.SyncbaseTable _getDecksTable() {
  return sb.database.table(decksTableName);
}

sb.SyncbaseTable _getPresentationsTable() {
  return sb.database.table(presentationsTableName);
}

sb.SyncbaseTable _getBlobsTable() {
  return sb.database.table(blobsTableName);
}
