<commit_before>/* eslint require-jsdoc:0 */
/* globals window */
import uuid from 'uuid';

import Media from '../media';
import PeerConnectionManager from '../peer-connection-manager';
import RoapInterface from '../roap/roap-interface.js';
import RoapAdapter from '../roap/roap-adapter.js';

import request from './request.js';

/**
  * Events to emit
  * ==============
  * - leave
  * - join
  * - end
  * - meeting.metrics {
  *   - media
  *   - MQE
  *   - callAnalyzer
  *   - meetingEndMetrics?
  * }
  * - statusChange {
  *   - status, e.g., leaving, left, reason
  * }
  * - typeChange {
  *   - type
      - reason
  * }
  *
  * @export
  * @class Meeting
  */
export default class Meeting {
  // /**
  //  * Create an instance of Meeting
  //  *
  //  * @param {string} options.id
  //  * @param {string} options.spaceID
  //  * @param {array} options.members
  //  * @param {object} options.peerConnections
  //  * @param {object} options.health
  //  * @param {string} options.type
  //  * @param {string} options.direction
  //  * @param {object} options.pairedDevice
  //  * @param {ISOString} options.startTime
  //  * @param {ISOString} options.endTime
  //  * @memberof Meeting
  //  */
  constructor(options) {
    this.id = uuid.v4();
    this.spark = options.spark;
    this.meetingInfo = options.meetingInfo;
    // THe passed in destination can have many ways of calling
    // sipUrl , convo Id etc we want to refer the meeting with same Ids
    // TODO: check for the destination and convert it into a sip uri if possible
    this.updateMeetingInfo(this.meetingInfo);
    this.sipUri = this.sipUri || options.destination;
    this.userId = this.spark.internal.device.userId;
    this.deviceUrl = this.spark.internal.device.url;
    this.resource = options.resourceId; // Can be a object, resource or self object
    this.roapSeq = 0;
    this.videoMuted = false;
    this.audioMuted = false;
    // this.peerConnectionManager = new PeerConnectionManager(config);
    // this.roapInterface = new RoapInterface();
    // this.stateMachine = new stateMachine(); //constants

    // this.memebers = members;
    // this.peerConnections = peerConnections;
    // this.health = health;
    // this.type = type;
    // this.direction = direction;
    // this.pairedDevice = pairedDevice;
    // this.startTime = startTime || new Date().toISOString();
    // this.endTime = endTime || new Date().toISOString();
  }

  updateMeetingInfo(meetingInfo) {
    // MeetingInfo will be undefined for 1:1 calls
    if (meetingInfo) {
      this.convoId = this.meetingInfo.convoId;
      this.locusUrl = this.meetingInfo.locusUrl;
      this.sipUri = this.meetingInfo.sipMeetingUri;
    }
  }

  joinMeeting() {
    // TODO: check if the meeting is in JOINING state
    // if JOining state termintate the request as user might click multiple times
    this.correlationId = this.id;
    return request
      .joinMeeting({
        sipUri: this.sipUri,
        deviceUrl: this.deviceUrl,
        locusUrl: this.locusUrl,
        correlationId: this.id
      })
      .then((res) => {
        window.meetings.put(this, this.id);
        // TODO: was thinking to have one function for parsing
        // all updates will give a locus object and we just need to
        // update the existing locus object and send events to the UI
        this._parseLocus(res);
      })
      .catch((err) => {
        console.log('ERROR JOINING CALL', err);
      });
  }

  _parseLocus(res) {
    // First todo: add check for existance
    this.locus = res.body.locus;
    this.mediaConnections = res.body.mediaConnections;
    this.locusUrl = this.locus.url;
    const temp = this.locus.url.split('/');
    this.locusId = temp.pop();
    this.selfId = this.locus.self.id;

    // we need mediaId before making roap calls
    this.mediaConnections.forEach((mediaConnection) => {
      if (mediaConnection.mediaId) {
        this.mediaId = mediaConnection.mediaId;
      }
    });
  }

  updateRoapSeq(seq) {
    this.roapSeq = seq;
  }

  addMedia(audioVideo, screen) {
    const promises = [];
    this.mediaDirection = {
      receiveAudio: true,
      receiveVideo: true
    };
    [document.getElementById('localvideo').srcObject] = audioVideo;
    if (this.mediaDirection.receiveVideo || this.mediaDirection.receiveAudio) {
      promises.push(
        PeerConnectionManager.createOffer({
          receiveAudio: this.mediaDirection.receiveAudio,
          receiveVideo: this.mediaDirection.receiveVideo,
          // After you get the localStream
          streams: audioVideo
        })
      );

      promises.push(
        PeerConnectionManager.createOffer({
          // its for screen sharing but can change in future when user wants just share with audio
          receiveAudio: false,
          receiveVideo: this.mediaDirection.receiveVideo,
          // After you get the localStream
          streams: screen
        })
      );
    }
    return Promise.all(promises);
  }

  getLocalMedia(options) {
    const {sendAudio, sendVideo, sendShare} = options;
    return Promise.try(() => Media.getScreenShare(sendShare))
      .then((screenConstraints) => Media.getMedia(false, screenConstraints))
      .then((screen) => Media.getMedia(sendAudio, sendVideo).then((media) => [media, screen]));
  }

  /**
   *
   * Specify joining via audio (option: pstn), video, screenshare
   * @exports
   * @param {object} [options={ PairedDevice, Password }]
   * @returns {Promise}
   * @memberof Meeting
   */
  join(options) {
    // let {mediaDirection} = options;

    const mediaDirection = {
      sendAudio: true,
      sendVideo: true,
      receiveAudio: true,
      receiveVideo: true,
      pstn: false,
      sendShare: false,
      receiveShare: false
    };
    return this.joinMeeting()
      .then(() => this.getLocalMedia({<commit_msg>fix(media): make calls work after merge<commit_after>/* eslint require-jsdoc:0 */
/* globals window */
import uuid from 'uuid';

import Media from '../media';
import PeerConnectionManager from '../peer-connection-manager';
import RoapInterface from '../roap/roap-interface.js';
import RoapAdapter from '../roap/roap-adapter.js';

import request from './request.js';

/**
  * Events to emit
  * ==============
  * - leave
  * - join
  * - end
  * - meeting.metrics {
  *   - media
  *   - MQE
  *   - callAnalyzer
  *   - meetingEndMetrics?
  * }
  * - statusChange {
  *   - status, e.g., leaving, left, reason
  * }
  * - typeChange {
  *   - type
      - reason
  * }
  *
  * @export
  * @class Meeting
  */
export default class Meeting {
  // /**
  //  * Create an instance of Meeting
  //  *
  //  * @param {string} options.id
  //  * @param {string} options.spaceID
  //  * @param {array} options.members
  //  * @param {object} options.peerConnections
  //  * @param {object} options.health
  //  * @param {string} options.type
  //  * @param {string} options.direction
  //  * @param {object} options.pairedDevice
  //  * @param {ISOString} options.startTime
  //  * @param {ISOString} options.endTime
  //  * @memberof Meeting
  //  */
  constructor(options) {
    this.id = uuid.v4();
    this.spark = options.spark;
    this.meetingInfo = options.meetingInfo;
    // THe passed in destination can have many ways of calling
    // sipUrl , convo Id etc we want to refer the meeting with same Ids
    // TODO: check for the destination and convert it into a sip uri if possible
    this.updateMeetingInfo(this.meetingInfo);
    this.sipUri = this.sipUri || options.destination;
    this.userId = this.spark.internal.device.userId;
    this.deviceUrl = this.spark.internal.device.url;
    this.resource = options.resourceId; // Can be a object, resource or self object
    this.roapSeq = 0;
    this.videoMuted = false;
    this.audioMuted = false;
    // this.peerConnectionManager = new PeerConnectionManager(config);
    // this.roapInterface = new RoapInterface();
    // this.stateMachine = new stateMachine(); //constants

    // this.memebers = members;
    // this.peerConnections = peerConnections;
    // this.health = health;
    // this.type = type;
    // this.direction = direction;
    // this.pairedDevice = pairedDevice;
    // this.startTime = startTime || new Date().toISOString();
    // this.endTime = endTime || new Date().toISOString();
  }

  updateMeetingInfo(meetingInfo) {
    // MeetingInfo will be undefined for 1:1 calls
    if (meetingInfo) {
      this.convoId = this.meetingInfo.convoId;
      this.locusUrl = this.meetingInfo.locusUrl;
      this.sipUri = this.meetingInfo.sipMeetingUri;
    }
  }

  joinMeeting() {
    // TODO: check if the meeting is in JOINING state
    // if JOining state termintate the request as user might click multiple times
    this.correlationId = this.id;
    return request
      .joinMeeting({
        sipUri: this.sipUri,
        deviceUrl: this.deviceUrl,
        locusUrl: this.locusUrl,
        correlationId: this.id
      })
      .then((res) => {
        window.meetings.put(this, this.id);
        // TODO: was thinking to have one function for parsing
        // all updates will give a locus object and we just need to
        // update the existing locus object and send events to the UI
        this._parseLocus(res);
      })
      .catch((err) => {
        console.log('ERROR JOINING CALL', err);
      });
  }

  _parseLocus(res) {
    // First todo: add check for existance
    this.locus = res.body.locus;
    this.mediaConnections = res.body.mediaConnections;
    this.locusUrl = this.locus.url;
    const temp = this.locus.url.split('/');
    this.locusId = temp.pop();
    this.selfId = this.locus.self.id;

    // we need mediaId before making roap calls
    this.mediaConnections.forEach((mediaConnection) => {
      if (mediaConnection.mediaId) {
        this.mediaId = mediaConnection.mediaId;
      }
    });
  }

  updateRoapSeq(seq) {
    this.roapSeq = seq;
  }

  addMedia(audioVideo, screen) {
    const promises = [];
    this.mediaDirection = {
      receiveAudio: true,
      receiveVideo: true
    };
    [document.getElementById('localvideo').srcObject] = audioVideo;
    if (this.mediaDirection.receiveVideo || this.mediaDirection.receiveAudio) {
      promises.push(
        PeerConnectionManager.createOffer({
          receiveAudio: this.mediaDirection.receiveAudio,
          receiveVideo: this.mediaDirection.receiveVideo,
          // After you get the localStream
          streams: audioVideo
        })
      );

      promises.push(
        PeerConnectionManager.createOffer({
          // its for screen sharing but can change in future when user wants just share with audio
          receiveAudio: false,
          receiveVideo: this.mediaDirection.receiveVideo,
          // After you get the localStream
          streams: screen
        })
      );
    }
    return Promise.all(promises);
  }

  getLocalMedia(options) {
    const {sendAudio, sendVideo, sendShare} = options;
    return Promise.try(() => /* Media.getScreenShare(sendShare))
      .then((screenConstraints) => Media.getMedia(false, screenConstraints))
      .then((screen) => */ Media.getMedia(sendAudio, sendVideo).then((media) => [media, screen]));
  }

  /**
   *
   * Specify joining via audio (option: pstn), video, screenshare
   * @exports
   * @param {object} [options={ PairedDevice, Password }]
   * @returns {Promise}
   * @memberof Meeting
   */
  join(options) {
    // let {mediaDirection} = options;

    const mediaDirection = {
      sendAudio: true,
      sendVideo: true,
      receiveAudio: true,
      receiveVideo: true,
      pstn: false,
      sendShare: false,
      receiveShare: false
    };
    return this.joinMeeting()
      .then(() => this.getLocalMedia({
{'fraction_non_alphanumeric': 0.12529853292391674, 'fraction_numerical': 0.0008529512111907199, 'mean_word_length': 2.5146882494004794, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6540934', 'n_tokens_mistral': 3603, 'n_tokens_neox': 3544, 'n_words': 874}