package org.datavaultplatform.broker.services;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.datavaultplatform.common.model.RoleAssignment;
import org.datavaultplatform.common.model.User;
import org.datavaultplatform.common.model.Vault;
import org.datavaultplatform.common.model.dao.VaultDAO;
import org.datavaultplatform.common.retentionpolicy.RetentionPolicy;

public class VaultsService {

    private VaultDAO vaultDAO;

    private RolesAndPermissionsService rolesAndPermissionsService;

    public void setRolesAndPermissionsService(RolesAndPermissionsService rolesAndPermissionsService) {
        this.rolesAndPermissionsService = rolesAndPermissionsService;
    }

    public List<Vault> getVaults() { return vaultDAO.list(); }

    public List<Vault> getVaults(String userId, String sort, String order, String offset, String maxResult) {
    	return vaultDAO.list(userId, sort, order, offset, maxResult);
    }

    public void addVault(Vault vault) {
        Date d = new Date();
        vault.setCreationTime(d);
        vaultDAO.save(vault);
    }

    public void orphanVault(Vault vault) {
        vault.setUser(null);
        vaultDAO.update(vault);
    }
    
    public void updateVault(Vault vault) {
        vaultDAO.update(vault);
    }
    
    public void saveOrUpdateVault(Vault vault) {
        vaultDAO.saveOrUpdateVault(vault);
    }
    
    public Vault getVault(String vaultID) {
        return vaultDAO.findById(vaultID);
    }
    
    public void setVaultDAO(VaultDAO vaultDAO) {
        this.vaultDAO = vaultDAO;
    }

    public List<Vault> search(String userId, String query, String sort, String order, String offset, String maxResult) {
        return this.vaultDAO.search(userId, query, sort, order, offset, maxResult);
    }

    public int count(String userId) { return vaultDAO.count(userId); }

    public int getRetentionPolicyCount(int status) { return vaultDAO.getRetentionPolicyCount(status); }

    public Vault checkRetentionPolicy (String vaultID) throws Exception {
        // Get the vault
        Vault vault = vaultDAO.findById(vaultID);

        // Get the right policy engine
        Class clazz = Class.forName(vault.getRetentionPolicy().getEngine());
        RetentionPolicy policy = (RetentionPolicy)clazz.newInstance();

        // Check the policy
        policy.run(vault);

        // Set the expiry date
        vault.setRetentionPolicyExpiry(policy.getReviewDate(vault));

        // Record when we checked it
        vault.setRetentionPolicyLastChecked(new Date());

        // Update and return the policy
        vaultDAO.update(vault);
        return vault;
    }
    
    // Get the specified Vault object and validate it against the current User
    public Vault getUserVault(User user, String vaultID) throws Exception {
        Vault vault = getVault(vaultID);

        if (vault == null) {
            throw new Exception("Vault '" + vaultID + "' does not exist");
        }

        return vault;
    }
 	
	public Long getTotalNumberOfVaults(String userId) {
		return vaultDAO.getTotalNumberOfVaults(userId);
	}

	/**
	 * Total number of records after applying search filter
	 * @param query
	 * @return
	 */
	public Long getTotalNumberOfVaults(String userId, String query) {
		return vaultDAO.getTotalNumberOfVaults(userId, query);
	}
	
	public Map<String, Long> getAllProjectsSize() {
		Map<String, Long> projectSizeMap = new HashMap<>();
		List<Object[]> allProjectsSize = vaultDAO.getAllProjectsSize();
		if(allProjectsSize != null) {
			for(Object[] projectsizeArray :allProjectsSize) {
				projectSizeMap.put((String)projectsizeArray[0], (Long)projectsizeArray[1]);
			}
		}
		return projectSizeMap;
	}

    public void transferVault(Vault vault, User newOwner, String reason) {
        vault.setUser(newOwner);
        vaultDAO.update(vault);

        RoleAssignment newDataOwnerAssignment = new RoleAssignment();
        newDataOwnerAssignment.setUser(newOwner);
        newDataOwnerAssignment.setVault(vault);
        newDataOwnerAssignment.setRole(rolesAndPermissionsService.getDataOwner());
        rolesAndPermissionsService.createRoleAssignment(newDataOwnerAssignment);
    }
}


@@ -194,16 +194,69 @@
 gnment;%0A
+import org.datavaultplatform.common.model.RoleModel;%0A
 import o
@@ -3924,32 +3924,434 @@
 update(vault);%0A%0A
+        RoleModel dataOwnerRole = rolesAndPermissionsService.getDataOwner();%0A        rolesAndPermissionsService.getRoleAssignmentsForRole(dataOwnerRole.getId()).stream()%0A                .filter(roleAssignment -%3E vault.equals(roleAssignment.getVault()))%0A                .findFirst()%0A                .ifPresent(roleAssignment -%3E rolesAndPermissionsService.deleteRoleAssignment(roleAssignment.getId()));%0A%0A
         RoleAssi
@@ -4400,24 +4400,24 @@
 signment();%0A
-
         newD
@@ -4545,47 +4545,17 @@
 ole(
-rolesAndPermissionsService.getD
+d
 ataOwner
 ());
@@ -4550,18 +4550,20 @@
 ataOwner
-()
+Role
 );%0A     
@@ -4644,11 +4644,10 @@
 ;%0A    %7D%0A
+
 %7D%0A
-%0A

Remove old data owner role assignment when transferring vault ownership