/*
 * NOTICE:  This file is owned by the chat and messaging team (#chat-and-messaging on slack)
 * If you make changes to this file or any of its chat-effecting dependencies, you must do the following two things:
 * 1)  Test chat and whispers in a staging environment
 * 2)  Get a PR approved by a member of the chat and messaging team
 *
 * Thanks!
 */

import Service from 'ember-service';

import Ember from 'ember';
import PubsubDriver from 'pubsub-js-client/PubsubDriver';

const { Evented, Logger, inject } = Ember;

export default Service.extend(Evented, {
  session: inject.service(),

  hasDisconnected: false,

  setupService() {
    return this.get('session').getCurrentUser().then((userData) => {
      if (this.isDestroyed) { return; }
      let pubsub = this._pubsub();
      let userId = userData.id;
      let oauthToken = userData.chat_oauth_token;

      let whispersTopic = `whispers.${userId}`;

      pubsub.Listen({
        topic: whispersTopic,
        auth: oauthToken,
        success: function () {},

        failure: function (err) {
          Logger.error(`Failed to listen to whispers topic: ${whispersTopic}`, err);
        },

        message: this._onPubsubMessage.bind(this)
      });

      pubsub.on("connected", this._onPubsubConnect.bind(this));
      pubsub.on("disconnected", this._onPubsubDisconnect.bind(this));
    });
  },

  _pubsub() {
    return PubsubDriver.getInstance('production');
  },

  _onPubsubConnect() {
    if (this.isDestroyed) { return; }
    if (this.get('hasDisconnected')) {
      this.trigger("reconnecting");
      this.set('hasDisconnected', false);
    }
  },

  _onPubsubDisconnect() {
    if (this.isDestroyed) { return; }
    this.set('hasDisconnected', true);
  },

  _onPubsubMessage(payload) {
    if (this.isDestroyed) { return; }
    let json = JSON.parse(payload);
    let type = json.type;
    let parsedData = json.data_object;

    if (type === "whisper_received" ||
        type === "whisper_sent") {
      this.trigger("whisper", parsedData);
    } else if (type === "thread") {
      this.trigger("thread", parsedData);
    } else if (type === "threads") {
      this.trigger("threads", parsedData);
    }
  }
});
