import ChannelBase from './channels/channelBase';
import ClientBase from './clients/clientBase';
import MHSClient from './clients/sites/mhsClient';
import MHSChannel from './channels/sites/mhsChannel';

var logger = require('./logger');

class ChannelManager {
  channels: ChannelBase[]|MHSChannel[] = [];

  constructor() {
    // create default channel...
    var channel: ChannelBase = new ChannelBase('default');
    this.channels.push(channel);
  }

  createChannel(data: any) {
    var channelExists: ChannelBase|MHSChannel|null = this.channelExists(data.channel);
    var channel: ChannelBase|MHSChannel;

    if (channelExists) {
      channel = channelExists;
      logger.accessLog.info(`Channel already exists: ${channel.id}`);
    } else {
      channel = this.createByChannelType(data);
      this.channels.push(channel);
      logger.accessLog.info(`Added channel to channel manager: ${channel.id}`);
    }

    return channel;
  }

  channelExists(channel_id: string) {
    for (let channel of this.channels) {
      if (channel.id == channel_id) {
        return channel;
      }
    }

    return null;
  }

  addClientToChannel(client: ClientBase|MHSClient, channel_id: string) {
    var channel: ChannelBase|MHSChannel|null = this.channelExists(channel_id);

    if (channel) {
      channel.addClient(client);
      client.connectToChannel(channel);
      return {'status': 'success'};
    } else {
      logger.accessLog.info(`channel with id ${channel_id} does not exist.`);
      return {'status': 'notice', 'message': `channel with id ${channel_id} does not exist.`};
    }
  }

  createByChannelType(data: any) {
    try {
      var Channel = require(`./channels/${data.client_type}s/${data.client}channel`);
      logger.accessLog.info(`attempting to create channel of type ${data.client}, channel id: ${data.channel}...`);
      return new Channel(data.channel);
    } catch (e) {
      logger.errorLog.info(e);
      logger.accessLog.info(`creating base channel: ${data.channel}`);
      return new ChannelBase(data.channel);
    }
  }

  removeClientFromChannel(client_id: number, channel_id: string) {
    var index: number = 0;

    for (let channel of this.channels) {
      if (channel.id == channel_id) {
        this.channels.splice(index, 1);
        if (channel.removeClient(client_id)) {
          logger.accessLog.info(`client removed from channel - channel: ${channel_id}, client: ${client_id}`);
          return true;
        } else {
          logger.errorLog.info(`client not removed from channel, or doesn't exist in channel - channel: ${channel_id}, client: ${client_id}`);
          return false
        }
      }

      index++;
    }

    return false;
  }
};

export default ChannelManager;

// { :client => 'mhs', :client_type => 'site', :user_id => 125, :user_type => 'user', :channel => 'mhs_1239' }
