package ca.corefacility.bioinformatics.irida.security.permissions;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import ca.corefacility.bioinformatics.irida.model.enums.ProjectRole;
import ca.corefacility.bioinformatics.irida.model.joins.Join;
import ca.corefacility.bioinformatics.irida.model.joins.impl.ProjectUserJoin;
import ca.corefacility.bioinformatics.irida.model.project.Project;
import ca.corefacility.bioinformatics.irida.model.project.ReferenceFile;
import ca.corefacility.bioinformatics.irida.model.user.User;
import ca.corefacility.bioinformatics.irida.repositories.joins.project.ProjectReferenceFileJoinRepository;
import ca.corefacility.bioinformatics.irida.repositories.joins.project.ProjectUserJoinRepository;
import ca.corefacility.bioinformatics.irida.repositories.referencefile.ReferenceFileRepository;
import ca.corefacility.bioinformatics.irida.repositories.user.UserRepository;

/**
 * Confirms that the authenticated user is allowed to modify a reference file.
 * 
 * 
 */
@Component
public class UpdateReferenceFilePermission extends BasePermission<ReferenceFile, Long> {

	public static final String PERMISSION_PROVIDED = "canUpdateReferenceFile";

	private final UserRepository userRepository;
	private final ProjectUserJoinRepository pujRepository;
	private final ProjectReferenceFileJoinRepository prfRepository;

	@Autowired
	public UpdateReferenceFilePermission(ReferenceFileRepository referenceFileRepository,
			UserRepository userRepository, ProjectUserJoinRepository pujRepository,
			ProjectReferenceFileJoinRepository prfRepository) {
		super(ReferenceFile.class, Long.class, referenceFileRepository);
		this.userRepository = userRepository;
		this.pujRepository = pujRepository;
		this.prfRepository = prfRepository;
	}

	@Override
	public String getPermissionProvided() {
		return PERMISSION_PROVIDED;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected boolean customPermissionAllowed(Authentication authentication, ReferenceFile targetDomainObject) {
		// get the logged in user
		User user = userRepository.loadUserByUsername(authentication.getName());
		// get the projects for the file
		List<Join<Project, ReferenceFile>> findProjectsForReferenceFile = prfRepository
				.findProjectsForReferenceFile(targetDomainObject);

		// for each project
		for (Join<Project, ReferenceFile> prJoin : findProjectsForReferenceFile) {
			// get the users on the project
			List<Join<Project, User>> usersForProject = pujRepository.getUsersForProject(prJoin.getSubject());
			for (Join<Project, User> pj : usersForProject) {
				ProjectUserJoin puJoin = (ProjectUserJoin) pj;
				// if the user is on the project, they can read the file
				if (puJoin.getObject().equals(user) && puJoin.getProjectRole().equals(ProjectRole.PROJECT_OWNER)) {
					return true;
				}
			}
		}

		return false;
	}

}

@@ -309,161 +309,14 @@
 del.
-enums.ProjectRole;%0Aimport ca.corefacility.bioinformatics.irida.model.joins.Join;%0Aimport ca.corefacility.bioinformatics.irida.model.joins.impl.ProjectUser
+joins.
 Join
@@ -461,69 +461,8 @@
 le;%0A
-import ca.corefacility.bioinformatics.irida.model.user.User;%0A
 impo
@@ -568,106 +568,8 @@
 ry;%0A
-import ca.corefacility.bioinformatics.irida.repositories.joins.project.ProjectUserJoinRepository;%0A
 impo
@@ -663,86 +663,8 @@
 ory;
-%0Aimport ca.corefacility.bioinformatics.irida.repositories.user.UserRepository;
 %0A%0A/*
@@ -953,65 +953,28 @@
 nal 
-UserRepository userRepository;%0A%09private final ProjectUser
+ProjectReferenceFile
 Join
@@ -977,34 +977,34 @@
 JoinRepository p
-uj
+rf
 Repository;%0A%09pri
@@ -1025,49 +1025,46 @@
 ject
-ReferenceFileJoinRepository prfRepository
+OwnerPermission projectOwnerPermission
 ;%0A%0A%09
@@ -1112,16 +1112,22 @@
 mission(
+final 
 Referenc
@@ -1174,50 +1174,34 @@
 %0A%09%09%09
-UserRepository userRepository, ProjectUser
+final ProjectReferenceFile
 Join
@@ -1212,18 +1212,18 @@
 sitory p
-uj
+rf
 Reposito
@@ -1233,56 +1233,59 @@
 %0A%09%09%09
+final 
 Project
-ReferenceFileJoinRepository prfRepository
+OwnerPermission projectOwnerPermission
 ) %7B%0A
@@ -1358,20 +1358,19 @@
 %0A%09%09this.
-user
+prf
 Reposito
@@ -1374,20 +1374,19 @@
 itory = 
-user
+prf
 Reposito
@@ -1401,74 +1401,54 @@
 is.p
-ujRepository = pujRepository;%0A%09%09this.prfRepository = prfRepository
+rojectOwnerPermission = projectOwnerPermission
 ;%0A%09%7D
@@ -1688,111 +1688,8 @@
 ) %7B%0A
-%09%09// get the logged in user%0A%09%09User user = userRepository.loadUserByUsername(authentication.getName());%0A
 %09%09//
@@ -1863,558 +1863,137 @@
 %0A%0A%09%09
-// for each project%0A%09%09for (Join%3CProject, ReferenceFile%3E prJoin : findProjectsForReferenceFile) %7B%0A%09%09%09// get the users on the project%0A%09%09%09List%3CJoin%3CProject, User%3E%3E usersForProject = pujRepository.getUsersForProject(prJoin.getSubject());%0A%09%09%09for (Join%3CProject, User%3E pj : usersForProject) %7B%0A%09%09%09%09ProjectUserJoin puJoin = (ProjectUserJoin) pj;%0A%09%09%09%09// if the user is on the project, they can read the file%0A%09%09%09%09if (puJoin
+return findProjectsForReferenceFile.stream()%0A%09%09%09%09.anyMatch(j -%3E projectOwnerPermission.isAllowed(authentication, j
 .get
-O
+Su
 bject()
-.equals(user) && puJoin.getProjectRole().equals(ProjectRole.PROJECT_OWNER)) %7B%0A%09%09%09%09%09return true;%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09return false
+))
 ;%0A%09%7D

Rewrite update reference file to use project owner permission.