var util = require('util');
var Promise = require('bluebird');
var PluginStreaming = require('./streaming');
var Stream = require('../../stream');
var Channel = require('../../channel');
var serviceLocator = require('../../service-locator');
var JanusError = require('../error');

function PluginVideo(id, type, session) {
  PluginVideo.super_.apply(this, arguments);
}

util.inherits(PluginVideo, PluginStreaming);

PluginVideo.TYPE = 'janus.plugin.cm.rtpbroadcast';

/**
 * @param {Object} message
 * @returns {Promise}
 */
PluginVideo.prototype.processMessage = function(message) {
  var janusMessage = message['janus'];

  if ('message' === janusMessage && 'create' === message['body']['request']) {
    return this.onCreate(message);
  }

  if ('message' === janusMessage && 'watch' === message['body']['request']) {
    return this.onWatch(message);
  }

  if ('message' === janusMessage && 'switch' === message['body']['request']) {
    return this.onSwitch(message);
  }

  return PluginVideo.super_.prototype.processMessage.call(this, message);
};

PluginVideo.prototype.isAllowedMessage = function(message) {
  if (PluginVideo.super_.prototype.isAllowedMessage(message)) {
    var isDisallowed = 'message' === message['janus'] && 'list' === message['body']['request'];
    return !isDisallowed;
  } else {
    return false;
  }
};

/**
 * @param {Object} message
 * @returns {Promise}
 */
PluginVideo.prototype.onCreate = function(message) {
  var plugin = this;
  this.session.connection.transactions.add(message['transaction'], function(response) {
    if (plugin._isSuccessResponse(response)) {
      var channel = Channel.generate(message['body']['id'], message['body']['channel_data']);
      plugin.setChannel(channel);
      plugin.stream = Stream.generate(channel, plugin);
      serviceLocator.get('logger').info('Added ' + plugin.stream + ' for ' + plugin);
      return serviceLocator.get('cm-api-client').publish(plugin.stream)
        .then(function() {
          serviceLocator.get('streams').add(plugin.stream);
          serviceLocator.get('logger').info('Storing ' + plugin.stream + ' for ' + plugin);
          return response;
        })
        .catch(function(error) {
          serviceLocator.get('http-client').detach(plugin);
          throw new JanusError.Error('Cannot publish: ' + plugin.stream + ' error: ' + error.message, 490, message['transaction']);
        });
    } else {
      return Promise.resolve(response);
    }
  });
  return Promise.resolve(message);
};

/**
 * @param {Object} message
 * @returns {Promise}
 */
PluginVideo.prototype.onWatch = function(message) {
  var plugin = this;
  this.session.connection.transactions.add(message['transaction'], function(response) {
    if (plugin._isSuccessResponse(response)) {
      var channel = serviceLocator.get('channels').getByNameAndData(message['body']['id'], message['body']['channel_data']);
      plugin.stream = Stream.generate(channel, plugin);
      serviceLocator.get('logger').info('Added ' + plugin.stream + ' for ' + plugin);
    }
    return Promise.resolve(response);
  });
  return Promise.resolve(message);
};

/**
 * @param {Object} message
 * @returns {Promise}
 */
PluginVideo.prototype.onSwitch = function(message) {
  var plugin = this;
  plugin.removeStream();
  var channel = serviceLocator.get('channels').getByNameAndData(message['body']['id'], message['body']['channel_data']);
  plugin.stream = Stream.generate(channel, plugin);
  serviceLocator.get('logger').info('Added ' + plugin.stream + ' for ' + plugin);
  plugin.session.connection.transactions.add(message['transaction'], function(response) {
    if (plugin._isSuccessResponse(response)) {
      return plugin.subscribe(response);
    } else {
      return Promise.resolve(response);
    }
  });
  return Promise.resolve(message);
};

module.exports = PluginVideo;

@@ -973,16 +973,220 @@
 );%0A  %7D%0A%0A
+  if ('event' === janusMessage && 'streaming' === message%5B'plugindata'%5D%5B'data'%5D%5B'streaming'%5D && 'stopped' === message%5B'plugindata'%5D%5B'data'%5D%5B'result'%5D%5B'status'%5D) %7B%0A    return this.onStopped(message);%0A  %7D%0A%0A
   return
@@ -4019,16 +4019,206 @@
 e);%0A%7D;%0A%0A
+/**%0A * @param %7BObject%7D message%0A * @returns %7BPromise%7D%0A */%0APluginVideo.prototype.onStopped = function(message) %7B%0A  if (this.channel) %7B%0A    this.removeChannel();%0A  %7D%0A  this.removeStream();%0A%7D;%0A%0A
 module.e

Add onStopped event