/*jslint node: true */
'use strict';

var async = require('asyncawait/async'),
    await = require('asyncawait/await'),
    VideoAnnotation = require('../modules/annotations/models/video-annotation');

module.exports = function(io) {
    io.sockets.on('connection', function(socket) {
        if (!socket.request ||
            !socket.request.session ||
            !socket.request.session.passport) {
            throw new Error('Cannot authenticate socket connection without passing a valid session.');
        }
        var user = socket.request.session.passport.user;
        var getAnnotationsAsync = async(function(videoId) {
            return await (VideoAnnotation.find({
                video_id: videoId
            }).sort('start').exec());
        });

        socket.on('annotations:get', async(function(params) {
            var videoId = params.video_id;
            var annotations = await (getAnnotationsAsync(videoId));

            // return annotations only to requester
            socket.emit('annotations:updated', annotations);
        }));

        socket.on('annotations:save', async(function(params) {
            // find annotation model from DB
            var annotation = await (VideoAnnotation.findById(params.annotation._id).exec());

            // update annotation properties
            if (annotation) {
                // Do not allow other users, except the author to
                // modify the annotation
                if (annotation.author !== user.username) {
                    return;
                }
                var model = params.annotation;

                annotation.start = model.start;
                annotation.end = model.end;
                annotation.text = model.text;
                annotation.position = model.position;
                annotation.size = model.size;
                annotation.type = model.type;

                // save to DB
                await (annotation.save());
            } else {
                //  set the author and
                // create new model in DB 
                params.annotation.author = user.username;
                annotation = await (VideoAnnotation.create(params.annotation));
            }
            var videoId = annotation.video_id;
            var annotations = await (getAnnotationsAsync(videoId));
            // notify all users about changes
            io.sockets.emit('annotations:updated', annotations);
        }));

        socket.on('annotations:delete', async(function(params) {
            try {
                var annotationId = params.id;

                // find annotation in db
                var annotation = await (VideoAnnotation.findById(annotationId).exec());
                if (!annotation) {
                    return;
                }

                var videoId = annotation.video_id;

                // remove annotation from db
                await (annotation.remove());
                var annotations = await (getAnnotationsAsync(videoId));

                // notify all users about changes
                io.sockets.emit('annotations:updated', annotations);
            } catch (e) {
                console.log(e);
            }
        }));

        socket.on('comments:post', async(function(params) {
            try {
                var annotationId = params.annotation_id;

                // find annotation in db
                var annotation = await (VideoAnnotation.findById(annotationId).exec());
                if (!annotation) {
                    return;
                }

                var comment = {
                    text: params.text,
                    author: user.username || 'Unknown'
                };

                annotation.comments.push(comment);

                // Save annotation
                await (annotation.save());

                // Notify users that the annotation
                // comments have been updated
                var eventName = annotationId + ':comments:updated';
                io.sockets.emit(eventName, {
                    comments: annotation.comments
                });
            } catch (e) {
                console.log(e);
            }
        }));

        socket.on('comments:remove', async(function(params) {
            try {
                var annotationId = params.annotation_id;
                var commentId = params.comment_id;

                var annotation = await (VideoAnnotation.findById(annotationId).exec());
                if (!annotation) {
                    return;
                }

                for (var i = 0; i < annotation.comments.length; i++) {
                    if (annotation.comments[i]._id.toString() === commentId) {
                        if (annotation.comments[i].author === user.username) {
                            console.log('removing comment', commentId);
                            annotation.comments[i].remove();
                            break;
                        }
                    }
                }

                // Save annotation
                await (annotation.save());

                var eventName = annotationId + ':comments:updated';
                io.sockets.emit(eventName, {
                    comments: annotation.comments
                });

            } catch (e) {
                console.log(e);
            }
        }));
    });
};

@@ -195,16 +195,228 @@
 ion');%0A%0A
+var checkSession = function(socket) %7B%0A    return socket &&%0A        socket.request &&%0A        socket.request.session &&%0A        socket.request.session.passport &&%0A        socket.request.session.passport.user;%0A%7D;%0A%0A
 module.e
@@ -435,24 +435,25 @@
 ction(io) %7B%0A
+%0A
     io.socke
@@ -495,296 +495,8 @@
 ) %7B%0A
-        if (!socket.request %7C%7C%0A            !socket.request.session %7C%7C%0A            !socket.request.session.passport) %7B%0A            throw new Error('Cannot authenticate socket connection without passing a valid session.');%0A        %7D%0A        var user = socket.request.session.passport.user;%0A
     
@@ -1182,24 +1182,158 @@
 id).exec());
+%0A            if (!checkSession()) %7B%0A                return;%0A            %7D%0A            var user = socket.request.session.passport.user;
 %0A%0A          
@@ -3608,33 +3608,182 @@
               %7D%0A
+                if (!checkSession()) %7B%0A                    return;%0A                %7D%0A                var user = socket.request.session.passport.user;
 %0A
-
                 
@@ -4742,32 +4742,32 @@
         return;%0A
-
                 
@@ -4759,32 +4759,182 @@
                %7D
+%0A                if (!checkSession()) %7B%0A                    return;%0A                %7D%0A                var user = socket.request.session.passport.user;
 %0A%0A              

improve authentication