const { projectOrganisations, vesselOrganisations/*, orgAccess */} = require('../../../lib/db/project/organisations');
const ServerUser = require('../../../lib/db/user/User');
const { Organisations } = require('@dougal/organisations');
const { ERROR, INFO, DEBUG } = require('DOUGAL_ROOT/debug')(__filename);

/** Second-order function.
 * Returns a middleware that checks if the user has access to
 * `operation` in the project identified by `req.params.project`
 * or, if `req.params.project` is not defined, against the vessel
 * access permissions.
 */
function operation (operation) {
	return async function (req, res, next) {
		const user = new ServerUser(req.user);
		if (req.params.project) {
			const projectOrgs = new Organisations(await projectOrganisations(req.params.project));
			const availableOrgs = projectOrgs.accessToOperation(operation).filter(user.organisations);
			DEBUG(`operation = ${operation}, user = ${user?.name}, user orgs = %j, project orgs = %j, availableOrgs = %j`, user.organisations.toJSON(), projectOrgs.toJSON(), availableOrgs.toJSON());
			if (availableOrgs.length > 0) {
				next();
				return;
			}
		} else {
			const vesselOrgs = new Organisations(await vesselOrganisations());
			const availableOrgs = vesselOrgs.accessToOperation(operation).filter(user.organisations);
			DEBUG(`operation = ${operation}, user = ${user?.name}, user orgs = %j, vessel orgs = %j, availableOrgs = %j`, user.organisations.toJSON(), vesselOrgs.toJSON(), availableOrgs.toJSON());
			if (availableOrgs.length > 0) {
				next();
				return;
			}
		}
		DEBUG(`Access denied to operation ${operation}.`);
		next({status: 403, message: "Access denied"});
	}
}
// function operation (operation) {
// 	return async function (req, res, next) {
// 		if (await orgAccess(req.user?.organisations, req.params.project ?? null, operation)) {
// 			next();
// 		} else {
// 			next({status: 403, message: "Access denied"});
// 		}
// 	}
// }

// Everyone can access
async function all (req, res, next) {
	next();
}

// Any logged in user can access
async function user (req, res, next) {
	if (req.user) {
		next();
	} else {
		next({status: 403, message: "Access denied"});
	}
}

// Any user who is an admin of at least one organisation
async function admin (req, res, next) {
	if (req.user) {
		const user = new ServerUser(req.user);
		if (user.organisations.accessToOperation("edit").length > 0) {
			next();
			return;
		}
	}
	next({status: 403, message: "Access denied"});
}

const read = operation('read');
const write = operation('write');
const edit = operation('edit');

module.exports = {
	all,
	user,
	read,
	write,
	edit,
	admin,
};
