1 var express = require('express');
  2 var router = express.Router();
  3 var verify = require('./verify');
  4 const bcrypt = require('bcryptjs');
  5 
  6 /**
  7 	* Middleware function to get event from database.
  8 	* API to access this function: GET /api/event
  9 	* @param {Object} req The express routing HTTP client request object.
 10 	* @param {Object} res The express routing HTTP client response object.
 11 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
 12 	* @return {Void}
 13 */
 14 var getEvent = function(req, res, next) {
 15 	var db = req.app.locals.db;
 16 	db.collection('Events')
 17 		.find().toArray(function(err, result) {
 18 			res.status(200).json(result);
 19 		});
 20 }
 21 
 22 router.get('/event', getEvent);
 23 
 24 /**
 25 	* Middleware function to get events from database that user with id userid is invited to.
 26 	* API to access this function: GET /api/events/:userid
 27 	* @param {Object} req The express routing HTTP client request object.
 28 	* @param {Object} res The express routing HTTP client response object.
 29 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
 30 	* @return {Void}
 31 */
 32 var getEventsUserID = function(req, res, next) {
 33 	var db = req.app.locals.db;
 34 	var userId = parseInt(req.params.userid);
 35 	db.collection('Events')
 36 		.find({'invitedIds': userId}).toArray(function(err, result) {
 37 			res.status(200).json(result);
 38 		});
 39 }
 40 
 41 router.get('/events/:userid', getEventsUserID);
 42 
 43 /**
 44 	* Middleware function to get events from database that user with id userid has been matched to.
 45 	* API to access this function: GET /api/matchedevents/:userid
 46 	* @param {Object} req The express routing HTTP client request object.
 47 	* @param {Object} res The express routing HTTP client response object.
 48 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
 49 	* @return {Void}
 50 */
 51 var getMatchedEventsUserID = function(req, res, next) {
 52 	var db = req.app.locals.db;
 53 	var userId = parseInt(req.params.userid);
 54 	db.collection('Events')
 55 		.find({'invitedIds': userId, 'status': 'matched'}).toArray(function(err, result) {
 56 			res.status(200).json(result);
 57 		});
 58 }
 59 
 60 
 61 router.get('/matchedevents/:userid', getMatchedEventsUserID);
 62 
 63 /**
 64 	* Middleware function to get confirmed events from database that user with id userid has been matched to.
 65 	* API to access this function: GET /api/confirmedevents/:userid
 66 	* @param {Object} req The express routing HTTP client request object.
 67 	* @param {Object} res The express routing HTTP client response object.
 68 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
 69 	* @return {Void}
 70 */
 71 var getConfirmedEventsUserID = function(req, res, next) {
 72 	var db = req.app.locals.db;
 73 	var userId = parseInt(req.params.userid);
 74 	db.collection('Events')
 75 		.find({'invitedIds': userId, 'status': 'confirmed'}).toArray(function(err, result) {
 76 			res.status(200).json(result);
 77 		});
 78 }
 79 
 80 
 81 router.get('/confirmedevents/:userid', getConfirmedEventsUserID);
 82 
 83 /**
 84 	* Middleware function to get pending events from database that user with id userid has been matched to.
 85 	* API to access this function: GET /api/pendingevents/:userid
 86 	* @param {Object} req The express routing HTTP client request object.
 87 	* @param {Object} res The express routing HTTP client response object.
 88 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
 89 	* @return {Void}
 90 */
 91 var getPendingEventsUserID = function(req, res, next) {
 92 	var db = req.app.locals.db;
 93 	var userId = parseInt(req.params.userid);
 94 	db.collection('Events')
 95 		.find({'invitedIds': userId, 'status': 'pending'}).toArray(function(err, result) {
 96 			res.status(200).json(result);
 97 		});
 98 }
 99 
100 router.get('/pendingevents/:userid', getPendingEventsUserID);
101 
102 /**
103 	* Middleware function to post an event to the database.
104 	* API to access this function: POST /api/event
105 	* @param {Object} req The express routing HTTP client request object.
106 	* @param {Object} res The express routing HTTP client response object.
107 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
108 	* @return {Void}
109 */
110 var postEvent = function(req, res, next) {
111 	var db = req.app.locals.db;
112 	db.collection('Values')
113 		.findOne({'name': 'Events'}, function(err, result) {
114 				if(req.body.event === undefined) {
115 					res.status(400).send('Bad request');
116 					return;
117 				}
118 				var eventId = Number(result.maxEventId);
119 				db.collection('Values').updateOne({'name': 'Events'}, {'maxEventId': eventId + 1}, function(err, result) {
120 					var event = req.body.event;
121 					event.eventId = eventId + 1;
122 					db.collection('Events').insertOne(event, function(err, result) {
123 						res.status(200).send('OK');
124 					});
125 				});
126 		});
127 }
128 
129 router.post('/event', postEvent);
130 
131 /**
132 	* Middleware function to update event in database with id eventId.
133 	* API to access this function: PUT /api/event/:eventId
134 	* @param {Object} req The express routing HTTP client request object.
135 	* @param {Object} res The express routing HTTP client response object.
136 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
137 	* @return {Void}
138 */
139 var putEventEventID = function(req, res, next) {
140 	var eventId = parseInt(req.params.eventId);
141 	var db = req.app.locals.db;
142 	var event = req.body.event;
143 	console.log(event);
144 	var updateObj = { $set: {acceptedIds: event.acceptedIds,
145 									status: event.status} };
146 
147 	db.collection('Events').updateOne({'eventId': eventId}, updateObj, function(err, result) {
148 					if (err) {
149 						console.log(errorHandler(err));
150 					}
151 					res.status(200).send('OK');
152 
153 				});
154 }
155 
156 router.put('/event/:eventId', putEventEventID);
157 
158 /**
159 	* Middleware function to delete event in database with id eventId.
160 	* API to access this function: DELETE /api/event/:eventId
161 	* @param {Object} req The express routing HTTP client request object.
162 	* @param {Object} res The express routing HTTP client response object.
163 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
164 	* @return {Void}
165 */
166 var deleteEventEventID = function(req, res, next) {
167 	var eventId = parseInt(req.params.eventId);
168 	var db = req.app.locals.db;
169 	db.collection('Events')
170 		.deleteOne({'eventId': eventId}, function(err, results) {
171 			res.status(200).send('OK');
172 		});
173 }
174 
175 router.delete('/event/:eventId', deleteEventEventID);
176 
177 /**
178 	* Middleware function to get array of JSON objects representing all users.
179 	* API to access this function: GET /api/users
180 	* @param {Object} req The express routing HTTP client request object.
181 	* @param {Object} res The express routing HTTP client response object.
182 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
183 	* @return {Void}
184 */
185 var getUsers = function(req, res, next) {
186 	var db = req.app.locals.db;
187 	var userId = parseInt(req.params.userid);
188 	var included_fields = {'userId': true, 'name': true, 'email': true, 'rating': true, 'activities': true, 'availability': true, 'events': true, '_id': false};
189 	db.collection('Users')
190 		.find().project(included_fields)
191 		.toArray(function(err, results) {
192 			if (results.length == 0) {
193 				res.status(404).send("404: userId not found");
194 			} else {
195 				res.status(200).json(results);
196 			}
197 		});
198 }
199 
200 router.get('/users', getUsers);
201 
202 /**
203 	* Middleware function to get user with id userid.
204 	* API to access this function: GET /api/:userid
205 	* @param {Object} req The express routing HTTP client request object.
206 	* @param {Object} res The express routing HTTP client response object.
207 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
208 	* @return {Void}
209 */
210 var getUserID = function(req, res, next) {
211 	var db = req.app.locals.db;
212 	var userId = parseInt(req.params.userid);
213 	var included_fields = {'userId': true, 'name': true, 'email': true, 'rating': true, 'activities': true, 'availability': true, 'events': true, '_id': false};
214 	db.collection('Users')
215 		.find({'userId': userId}).project(included_fields)
216 		.toArray(function(err, results) {
217 			if (results.length == 0) {
218 				res.status(404).send("404: userId not found");
219 			} else {
220 				user = results[0]; // should only be one match
221 				res.status(200).json(user);
222 			}
223 		});
224 }
225 
226 router.get('/:userid', getUserID);
227 
228 /**
229 	* Middleware function to put a name into the user with id userid.
230 	* API to access this function: PUT /api/name/:userid
231 	* @param {Object} req The express routing HTTP client request object.
232 	* @param {Object} res The express routing HTTP client response object.
233 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
234 	* @return {Void}
235 */
236 var putNameUserID = function(req, res, next) {
237 	var db = req.app.locals.db;
238 	var userId = parseInt(req.params.userid);
239 	db.collection('Users')
240 		.find({'userId': userId})
241 		.toArray(function(err, results) {
242 			if (results.length == 0) {
243 				res.status(404).send("404: userId not found");
244 			} else {
245 				user = results[0]; // should only be one match
246 
247 				if (!verify.checkLogin(req.cookies.jwt, user.email)) {
248 					res.status(401).redirect('/login');
249 					return;
250 				}
251 				if(req.body.name === undefined) {
252 					res.status(400).send('Bad request');
253 					return;
254 				}
255 				var updated = {$set: {name: req.body.name}};
256 				db.collection('Users').updateOne({'userId': userId}, updated, function(err, result) {
257 					res.status(200).send('OK');
258 				});
259 			}
260 		});
261 }
262 
263 router.put('/name/:userid', putNameUserID);
264 
265 /**
266 	* Middleware function to update an availability cell for user with id userid.
267 	* API to access this function: PUT /api/availability/:userid
268 	* @param {Object} req The express routing HTTP client request object.
269 	* @param {Object} res The express routing HTTP client response object.
270 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
271 	* @return {Void}
272 */
273 var putAvailabilityUserID = function(req, res, next) {
274 	var db = req.app.locals.db;
275 	var userId = parseInt(req.params.userid);
276 	db.collection('Users')
277 		.find({'userId': userId})
278 		.toArray(function(err, results) {
279 			if (results.length == 0) {
280 				res.status(404).send("404: userId not found");
281 			} else {
282 				user = results[0]; // should only be one match
283 
284 				if (!verify.checkLogin(req.cookies.jwt, user.email)) {
285 					res.status(401).redirect('/login');
286 					return;
287 				}
288 				if(req.body.availability === undefined) {
289 					res.status(400).send('Bad request');
290 					return;
291 				}
292 				var updated = {$set: {availability: req.body.availability}};
293 				db.collection('Users').updateOne({'userId': userId}, updated, function(err, result) {
294 					res.status(200).send('OK');
295 				});
296 			}
297 		});
298 }
299 
300 router.put('/availability/:userid', putAvailabilityUserID);
301 
302 /**
303 	* Middleware function to update the password for user with id userid.
304 	* API to access this function: PUT /api/password/:userid
305 	* @param {Object} req The express routing HTTP client request object.
306 	* @param {Object} res The express routing HTTP client response object.
307 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
308 	* @return {Void}
309 */
310 var putPasswordUserID = function(req, res, next) {
311 	var db = req.app.locals.db;
312 	var userId = parseInt(req.params.userid);
313 	db.collection('Users')
314 		.find({'userId': userId})
315 		.toArray(function(err, results) {
316 			if (results.length == 0) {
317 				res.status(404).send("404: userId not found");
318 			} else {
319 				user = results[0]; // should only be one match
320 
321 				if (!verify.checkLogin(req.cookies.jwt, user.email)) {
322 					res.status(401).redirect('/login');
323 					return;
324 				}
325 				if(req.body.password === undefined) {
326 					res.status(400).send('Bad request');
327 					return;
328 				}
329 				bcrypt.hash(req.body.password, 10, function(err, hash) {
330 					var updated = {$set: {password: hash}};
331 					db.collection('Users').updateOne({'userId': userId}, updated, function(err, result) {
332 						res.status(200).send('OK');
333 					});
334 				});
335 			}
336 		});
337 }
338 
339 router.put('/password/:userid', putPasswordUserID);
340 
341 /**
342 	* Middleware function to update an activity for user with id userid.
343 	* API to access this function: POST /api/activity/:userid
344 	* @param {Object} req The express routing HTTP client request object.
345 	* @param {Object} res The express routing HTTP client response object.
346 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
347 	* @return {Void}
348 */
349 var postActivityUserID = function(req, res, next) {
350 	var db = req.app.locals.db;
351 	var userId = parseInt(req.params.userid);
352 	db.collection('Users')
353 		.find({'userId': userId})
354 		.toArray(function(err, results) {
355 			if (results.length == 0) {
356 				res.status(404).send("404: userId not found");
357 			} else {
358 				user = results[0]; // should only be one match
359 
360 				if (!verify.checkLogin(req.cookies.jwt, user.email)) {
361 					res.status(401).redirect('/login');
362 					return;
363 				}
364 				if(req.body.activity === undefined) {
365 					res.status(400).send('Bad request');
366 					return;
367 				}
368 				user.activities = req.body.activity;
369 				var updated = {$set: {activities: user.activities}};
370 				db.collection('Users').updateOne({'userId': userId}, updated, function(err, result) {
371 					res.status(200).send('OK');
372 				});
373 			}
374 		});
375 }
376 
377 router.post('/activity/:userid', postActivityUserID);
378 
379 // router.put('/activity/:userid',
380 	// function(req, res, next) {
381 	// var db = req.app.locals.db;
382 	// var userId = parseInt(req.params.userid);
383 	// db.collection('Users')
384 		// .find({'userId': userId})
385 		// .toArray(function(err, results) {
386 			// if (results.length == 0) {
387 				// res.status(404).send("404: userId not found");
388 			// } else {
389 				// user = results[0]; // should only be one match
390 
391 				// if (!verify.checkLogin(req.cookies.jwt, user.email)) {
392 					// res.status(401).redirect('/login');
393 					// return;
394 				// }
395 				// if(req.body.activity === undefined) {
396 					// res.status(400).send('Bad request');
397 					// return;
398 				// }
399 				// var updated_activity = JSON.parse(req.body.activity);
400 				// var ind = user.activities.findIndex(cur => cur.name === updated_activity.name);
401 				// if (ind === -1) {
402 					// res.status(400).send('Bad request');
403 					// return;
404 				// }
405 				// user.activities[ind] = updated_activity;
406 				// var updated = {$set: {activities: user.activities}};
407 				// db.collection('Users').updateOne({'userId': userId}, updated, function(err, result) {
408 					// res.status(200).send('OK');
409 				// });
410 			// }
411 		// });
412 // });
413 
414 /**
415 	* Middleware function to delete an activity for user with id userid.
416 	* API to access this function: DELETE /api/activity/:userid
417 	* @param {Object} req The express routing HTTP client request object.
418 	* @param {Object} res The express routing HTTP client response object.
419 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
420 	* @return {Void}
421 */
422 var deleteActivityUserID = function(req, res, next) {
423 	var db = req.app.locals.db;
424 	var userId = parseInt(req.params.userid);
425 	db.collection('Users')
426 		.find({'userId': userId})
427 		.toArray(function(err, results) {
428 			if (results.length == 0) {
429 				res.status(404).send("404: userId not found");
430 			} else {
431 				user = results[0]; // should only be one match
432 
433 				if (!verify.checkLogin(req.cookies.jwt, user.email)) {
434 					res.status(401).redirect('/login');
435 					return;
436 				}
437 				if(req.body.activity === undefined) {
438 					res.status(400).send('Bad request');
439 					return;
440 				}
441 				var ind = user.activities.findIndex(cur => cur.name === req.body.activity);
442 				if (ind === -1) {
443 					res.status(400).send('Bad request');
444 					return;
445 				}
446 				user.activities.splice(ind, 1);
447 				var updated = {$set: {activities: user.activities}};
448 				db.collection('Users').updateOne({'userId': userId}, updated, function(err, result) {
449 					res.status(200).send('OK');
450 				});
451 			}
452 		});
453 }
454 
455 router.delete('/activity/:userid', deleteActivityUserID);
456 
457 /**
458 	* Middleware function to let a user rate another user for an event.
459 	* API to access this function: PUT /api/rate/:userid
460 	* @param {Object} req The express routing HTTP client request object.
461 	* @param {Object} res The express routing HTTP client response object.
462 	* @param {callback} next The express routing callback function to invoke next middleware in the stack.
463 	* @return {Void}
464 */
465 var putRateUserID = function(req, res, next) {
466 	var db = req.app.locals.db;
467 	var userId = parseInt(req.params.userid);
468 	db.collection('Users')
469 		.find({'userId': userId})
470 		.toArray(function(err, results) {
471 			if (results.length == 0) {
472 				res.status(404).send("404: userId not found");
473 			} else {
474 				user = results[0]; // should only be one match
475 
476 				if (!verify.checkLogin(req.cookies.jwt, user.email)) {
477 					res.status(401).redirect('/login');
478 					return;
479 				}
480 				if(req.body.score === undefined || req.body.ratee === undefined || req.body.eventId === undefined) {
481 					res.status(400).send('Bad request');
482 					return;
483 				}
484 				var userId2 = parseInt(req.body.ratee);
485 				var ind = user.events.findIndex(cur => Number(req.body.eventId) === cur.eventId);
486 				if (ind === -1) {
487 					res.status(400).send('Bad request');
488 					return;
489 				}
490 				var new_ind = user.events[ind].rated.indexOf(userId2);
491 				if (new_ind !== -1) {
492 					res.status(400).send('Bad request');
493 					return;
494 				}
495 				user.events[ind].rated.push(userId2);
496 
497 				db.collection('Users')
498 					.find({'userId': userId2})
499 					.toArray(function(err, results2) {
500 						if (results2.length == 0)
501 							res.status(404).send("404: userId not found");
502 						user2 = results2[0]; // should only be one match
503 						user2.rating.scoreSum += Number(req.body.score);
504 						user2.rating.numRatings += 1;
505 						var updated = {$set: {rating: user2.rating}};
506 						db.collection('Users').updateOne({'userId': userId2}, updated, function(err, result) {
507 							updated = {$set: {events: user.events}}
508 							db.collection('Users').updateOne({'userId': userId}, updated, function(err, result2) {
509 								res.status(200).send('OK');
510 							});
511 						});
512 				});
513 			}
514 		});
515 }
516 
517 router.put('/rate/:userid', putRateUserID);
518 
519 module.exports = router;
520