'use strict';

const globalHooks = require('../../../hooks');
const hooks = require('feathers-hooks');
const auth = require('feathers-authentication');
const _ = require('lodash');
const ClassModel = require('../model').classModel;
const CourseModel = require('../model').courseModel;

const restrictToCurrentSchool = globalHooks.ifNotLocal(globalHooks.restrictToCurrentSchool);

/**
 * adds all students to a course when a class is added to the course
 * @param hook - contains created/patched object und request body
 */
const addWholeClassToCourse = (hook) => {
	let requestBody = hook.data;
	let course = hook.result;
	if ((requestBody.classIds || []).length > 0) { // just courses do have a property "classIds"
		return Promise.all(requestBody.classIds.map(classId => {
			return ClassModel.findById(classId).exec().then(c =>  c.userIds);
		})).then(studentIds => {
			// flatten deep arrays and remove duplicates
			studentIds = _.uniqWith(_.flattenDeep(studentIds), (e1, e2) => JSON.stringify(e1) === JSON.stringify(e2));

			// add all students of classes to course, if not already added
			return Promise.all(studentIds.map(s => {
				if (course.userIds.indexOf(s) < 0) {
					return CourseModel.update({_id: course._id}, {$push: {userIds: s}}).exec();
				} else {
					return {};
				}
			})).then(_ => hook);
		});
	} else {
		return hook;
	}
};

exports.before = {
	all: [auth.hooks.authenticate('jwt')],
	find: [restrictToCurrentSchool],
	get: [],
	create: [],
	update: [restrictToCurrentSchool],
	patch: [restrictToCurrentSchool],
	remove: [restrictToCurrentSchool]
};

exports.after = {
	all: [],
	find: [],
	get: [globalHooks.ifNotLocal(globalHooks.denyIfNotCurrentSchool({errorMessage: 'Die angefragte Gruppe gehört nicht zur eigenen Schule!'}))],
	create: [addWholeClassToCourse],
	update: [],
	patch: [addWholeClassToCourse],
	remove: []
};

@@ -495,17 +495,17 @@
  object 
-u
+a
 nd reque
@@ -1348,24 +1348,1518 @@
 ook;%0A%09%7D%0A%7D;%0A%0A
+/**%0A * deletes all students from a course when a class is removed from the course%0A * this function goes into a before hook before we have to check whether there is a class missing%0A * in the patch-body which was in the course before%0A * @param hook - contains and request body%0A */%0Aconst deleteWholeClassFromCourse = (hook) =%3E %7B%0A%09let requestBody = hook.data;%0A%09let courseId = hook.id;%0A%09return CourseModel.findById(courseId).exec().then(course =%3E %7B%0A%09%09if (!course) return hook;%0A%09%09%0A%09%09let removedClasses = _.differenceBy(course.classIds, requestBody.classIds, (v) =%3E JSON.stringify(v));%0A%09%09if (removedClasses.length %3C 1) return hook;%0A%09%09return Promise.all(removedClasses.map(classId =%3E %7B%0A%09%09%09return ClassModel.findById(classId).exec().then(c =%3E  c.userIds);%0A%09%09%7D)).then(studentIds =%3E %7B%0A%09%09%09// flatten deep arrays and remove duplicates%0A            studentIds = _.uniqWith(_.flattenDeep(studentIds), (e1, e2) =%3E JSON.stringify(e1) === JSON.stringify(e2));%0A%0A%09%09%09// remove all students of classes from course, if they are in course%0A%09%09%09return Promise.all(studentIds.map(s =%3E %7B%0A%09%09%09%09if (course.userIds.indexOf(s) %3E= 0) %7B%0A%09%09%09%09%09return CourseModel.update(%7B_id: course._id%7D, %7B$pull: %7BuserIds: s%7D%7D).exec();%0A%09%09%09%09%7D else %7B%0A%09%09%09%09%09return %7B%7D;%0A%09%09%09%09%7D%0A%09%09%09%7D)).then(result =%3E %7B%0A%0A%09%09%09%09// also remove all students from request body for not reading them in after hook%0A%09%09%09%09requestBody.userIds = _.differenceBy(requestBody.userIds, studentIds, (v) =%3E JSON.stringify(v));%0A%09%09%09%09hook.data = requestBody;%0A%09%09%09%09return hook;%0A%09%09%09%7D);%0A%09%09%7D);%0A%09%7D);%0A%7D%0A%0A
 exports.befo
@@ -2998,16 +2998,16 @@
 chool%5D,%0A
-
 %09patch: 
@@ -3026,24 +3026,52 @@
 urrentSchool
+, deleteWholeClassFromCourse
 %5D,%0A%09remove: 

add hook function for removing all class-students from course (#243)