// SSEConnection.js
var sseDirPath = 'https://webrtcweb.com/SSE/';

function SSEConnection(connection, connectCallback) {
    if (connection.socketURL && connection.socketURL !== '/') {
        sseDirPath = connection.socketURL;
    }

    // connection.trickleIce = false;
    connection.socket = new EventSource(sseDirPath + 'SSE.php?me=' + connection.userid);

    var skipDuplicate = {};
    connection.socket.onmessage = function(e) {
        if (skipDuplicate[e.data]) {
            return;
        }
        skipDuplicate[e.data] = true;

        if (!e.data.length) return;
        var data = e.data;
        try {
            data = JSON.parse(e.data);
        } catch (e) {
            return;
        }
        if (!data) return;

        if (data.remoteUserId) {
            if (data.eventName === connection.socketMessageEvent) {
                onMessagesCallback(data.data);
            }
            return;
        }

        Object.keys(data).forEach(function(key) {
            var message = data[key];
            if (!message.length) return;

            if (message instanceof Array) {
                message.forEach(function(m) {
                    m = JSON.parse(m);
                    if (!m) return;

                    if (m.eventName === connection.socketMessageEvent) {
                        onMessagesCallback(m.data);
                    }
                });
                return;
            }

            message = JSON.parse(message);
            if (!message) return;

            if (message.eventName === connection.socketMessageEvent) {
                onMessagesCallback(message.data);
            }
        });
    };

    connection.socket.emit = function(eventName, data, callback) {
        if (!eventName || !data) return;
        if (eventName === 'changed-uuid' || eventName === 'check-presence') {
            return;
        }
        if (data.message && data.message.shiftedModerationControl) return;

        if (!data.remoteUserId) return;

        var message = JSON.stringify({
            eventName: eventName,
            data: data
        });

        var hr = new XMLHttpRequest();
        hr.open('POST', sseDirPath + 'publish.php');

        var formData = new FormData();
        formData.append('data', message);
        formData.append('sender', connection.userid);
        formData.append('receiver', data.remoteUserId);
        hr.send(formData);

        if (callback) {
            callback();
        }
    };

    connection.socket.onopen = function() {
        if (connectCallback) {
            if (connection.enableLogs) {
                console.info('SSE connection is opened.');
            }

            // this event tries to open json file on server
            connection.socket.emit('fake_EventName', {
                remoteUserId: connection.userid
            });

            connectCallback(connection.socket);
            connectCallback = null;
        }
    };

    var mPeer = connection.multiPeersHandler;

    function onMessagesCallback(message) {
        if (message.remoteUserId != connection.userid) return;

        if (connection.peers[message.sender] && connection.peers[message.sender].extra != message.message.extra) {
            connection.peers[message.sender].extra = message.message.extra;
            connection.onExtraDataUpdated({
                userid: message.sender,
                extra: message.message.extra
            });
        }

        if (message.message.streamSyncNeeded && connection.peers[message.sender]) {
            var stream = connection.streamEvents[message.message.streamid];
            if (!stream || !stream.stream) {
                return;
            }

            var action = message.message.action;

            if (action === 'ended' || action === 'stream-removed') {
                connection.onstreamended(stream);
                return;
            }

            var type = message.message.type != 'both' ? message.message.type : null;
            stream.stream[action](type);
            return;
        }

        if (message.message === 'connectWithAllParticipants') {
            if (connection.broadcasters.indexOf(message.sender) === -1) {
                connection.broadcasters.push(message.sender);
            }

            mPeer.onNegotiationNeeded({
                allParticipants: connection.getAllParticipants(message.sender)
            }, message.sender);
            return;
        }

        if (message.message === 'removeFromBroadcastersList') {
            if (connection.broadcasters.indexOf(message.sender) !== -1) {
                delete connection.broadcasters[connection.broadcasters.indexOf(message.sender)];
                connection.broadcasters = removeNullEntries(connection.broadcasters);
            }
            return;
        }

        if (message.message === 'dropPeerConnection') {
            connection.deletePeer(message.sender);
            return;
        }

        if (message.message.allParticipants) {
            if (message.message.allParticipants.indexOf(message.sender) === -1) {
                message.message.allParticipants.push(message.sender);
            }

            message.message.allParticipants.forEach(function(participant) {
                mPeer[!connection.peers[participant] ? 'createNewPeer' : 'renegotiatePeer'](participant, {
                    localPeerSdpConstraints: {
                        OfferToReceiveAudio: connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                        OfferToReceiveVideo: connection.sdpConstraints.mandatory.OfferToReceiveVideo
                    },
                    remotePeerSdpConstraints: {
                        OfferToReceiveAudio: connection.session.oneway ? !!connection.session.audio : connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                        OfferToReceiveVideo: connection.session.oneway ? !!connection.session.video || !!connection.session.screen : connection.sdpConstraints.mandatory.OfferToReceiveVideo
                    },
                    isOneWay: !!connection.session.oneway || connection.direction === 'one-way',
                    isDataOnly: isData(connection.session)
                });
            });
            return;
        }

        if (message.message.newParticipant) {
            if (message.message.newParticipant == connection.userid) return;
            if (!!connection.peers[message.message.newParticipant]) return;

            mPeer.createNewPeer(message.message.newParticipant, message.message.userPreferences || {
                localPeerSdpConstraints: {
                    OfferToReceiveAudio: connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                    OfferToReceiveVideo: connection.sdpConstraints.mandatory.OfferToReceiveVideo
                },
                remotePeerSdpConstraints: {
                    OfferToReceiveAudio: connection.session.oneway ? !!connection.session.audio : connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                    OfferToReceiveVideo: connection.session.oneway ? !!connection.session.video || !!connection.session.screen : connection.sdpConstraints.mandatory.OfferToReceiveVideo
                },
                isOneWay: !!connection.session.oneway || connection.direction === 'one-way',
                isDataOnly: isData(connection.session)
            });
            return;
        }

        if (message.message.readyForOffer || message.message.addMeAsBroadcaster) {
            connection.addNewBroadcaster(message.sender);
        }

        if (message.message.newParticipationRequest && message.sender !== connection.userid) {
            if (connection.peers[message.sender]) {
                connection.deletePeer(message.sender);
            }

            var userPreferences = {
                extra: message.message.extra || {},
                localPeerSdpConstraints: message.message.remotePeerSdpConstraints || {
                    OfferToReceiveAudio: connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                    OfferToReceiveVideo: connection.sdpConstraints.mandatory.OfferToReceiveVideo
                },
                remotePeerSdpConstraints: message.message.localPeerSdpConstraints || {
                    OfferToReceiveAudio: connection.session.oneway ? !!connection.session.audio : connection.sdpConstraints.mandatory.OfferToReceiveAudio,
                    OfferToReceiveVideo: connection.session.oneway ? !!connection.session.video || !!connection.session.screen : connection.sdpConstraints.mandatory.OfferToReceiveVideo
                },
                isOneWay: typeof message.message.isOneWay !== 'undefined' ? message.message.isOneWay : !!connection.session.oneway || connection.direction === 'one-way',
                isDataOnly: typeof message.message.isDataOnly !== 'undefined' ? message.message.isDataOnly : isData(connection.session),
                dontGetRemoteStream: typeof message.message.isOneWay !== 'undefined' ? message.message.isOneWay : !!connection.session.oneway || connection.direction === 'one-way',
                dontAttachLocalStream: !!message.message.dontGetRemoteStream,
                connectionDescription: message,
                successCallback: function() {
                    // if its oneway----- todo: THIS SEEMS NOT IMPORTANT.
                    if (typeof message.message.isOneWay !== 'undefined' ? message.message.isOneWay : !!connection.session.oneway || connection.direction === 'one-way') {
                        connection.addNewBroadcaster(message.sender, userPreferences);
                    }

                    if (!!connection.session.oneway || connection.direction === 'one-way' || isData(connection.session)) {
                        connection.addNewBroadcaster(message.sender, userPreferences);
                    }
                }
            };

            connection.onNewParticipant(message.sender, userPreferences);
            return;
        }

        if (message.message.shiftedModerationControl) {
            connection.onShiftedModerationControl(message.sender, message.message.broadcasters);
            return;
        }

        if (message.message.changedUUID) {
            if (connection.peers[message.message.oldUUID]) {
                connection.peers[message.message.newUUID] = connection.peers[message.message.oldUUID];
                delete connection.peers[message.message.oldUUID];
            }
        }

        if (message.message.userLeft) {
            mPeer.onUserLeft(message.sender);

            if (!!message.message.autoCloseEntireSession) {
                connection.leave();
            }

            return;
        }

        mPeer.addNegotiatedMessage(message.message, message.sender);
    }

    function isData(session) {
        return !session.audio && !session.video && !session.screen && session.data;
    }
}

SSEConnection.checkPresence = function(roomid, callback) {
    callback = callback || function() {};

    if (connection.socketURL && connection.socketURL !== '/') {
        sseDirPath = connection.socketURL;
    }

    var hr = new XMLHttpRequest();
    hr.responseType = 'json';
    hr.response = {
        isRoomExist: false
    };
    hr.addEventListener('load', function() {
        if (connection.enableLogs) {
            console.info('XMLHttpRequest', hr.response);
        }
        callback(hr.response.isRoomExist, roomid);
    });
    hr.addEventListener('error', function() {
        callback(hr.response.isRoomExist, roomid);
    });
    hr.open('GET', sseDirPath + 'checkPresence.php?roomid=' + roomid);
    hr.send();
}
