package com.k_int.aggregator.dpp.util;

import java.security.Principal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;

import com.k_int.aggregator.datamodel.AggregatorCollectionHDO;
import com.k_int.svc.identity.service.IdentityService;
import com.k_int.svc.identity.service.IdentityServiceException;
import com.k_int.svc.identity.service.TargetObjectIdentifier;

/**
 * A simple class to provide utility functions related to editing permissions
 * 
 * @author rpb rich@k-int.com
 * @version 1.0 11.11.09
 */
public class PermissionUtils {

	
	private static Log log = LogFactory.getLog(PermissionUtils.class);

	
	public static boolean canUserEditResource(ApplicationContext ctx, HttpServletRequest request, Set<AggregatorCollectionHDO> colls) {
		boolean returnValue = false;
		
		if ( request.isUserInRole("SYSTEM.admin") || request.isUserInRole("GLOBAL.admin") ) {
			// Admin user..
			returnValue = true;
		} else {
			if ( colls == null || colls.size() == 0 ) {
				// The resource isn't in a collection - have to assume it is editable
				log.debug("resource isn't in a collection - assuming its ok to edit");
				returnValue = true;
			} else {
				// Check that at least one of the collections is editable for this user
				Principal principal = request.getUserPrincipal();
				if ( principal != null ) {
					Iterator<AggregatorCollectionHDO> collIter = colls.iterator();
					while(collIter.hasNext()) {
						AggregatorCollectionHDO nextColl = collIter.next();
						if ( nextColl != null ) {
							if ( validateEditPermission(ctx, principal.getName(), nextColl.getId()) ) {
								log.debug("have edit permissions for user: " + principal.getName() + " on collection: " + nextColl.getId());
								returnValue = true;
								break;
							}
						}
					}
				} else {
					log.error("Got to the EditItemRecord action without a user principal...");
					returnValue = false;
				}
			}
		}

		return returnValue;
	}
	
	  public static boolean validateEditPermission(ApplicationContext ctx, String editor_id, Long collId) 
	  {
	    boolean result = false;
	    try 
	    {      
	      IdentityService ident_service = (IdentityService) ctx.getBean("IdentityService");
	      SessionFactory factory = (SessionFactory)ctx.getBean("AggregatorSessionFactory");
	      
	      boolean editor = ident_service.hasRole(editor_id, "com.k_int.aggregator.roles.Editor");
	      if(editor)
	      {
	          Session sess=null;
	          
	          try
	          {
	              sess = factory.openSession();
    	          Map<Long, AggregatorCollectionHDO> valid_collections = getValidCollectionsForEditor(sess, ident_service,editor_id);
    	    
    	          if ( valid_collections.keySet().contains(collId) ) 
    	          {
    	            result = true;
    	          }
	          }
	          catch(Exception e)
	          {
	              log.error(e);
	              e.printStackTrace();
	          }
	          finally 
	          {
	              try 
	              {
	                  if(sess!=null)
	                      sess.close();
	              }
	              catch ( Exception e ) 
	              {
	                e.printStackTrace();
	              }
	            }
	          
	          
	      }
	    }
	    catch(Exception e )
	    {
	        log.error(e);
	    }
	    finally {
	    }
	    return result;
	  }

	  public static Map<Long, AggregatorCollectionHDO> getValidCollectionsForEditor(Session sess, IdentityService ident_service, String editor_id) {

		    Map<Long, AggregatorCollectionHDO> collections = new HashMap<Long, AggregatorCollectionHDO>();

		    try {
		    	
		    	Long edit_id = ident_service.usernameToId(editor_id);
		    	
		      TargetObjectIdentifier[] grants = ident_service.listGrantsFor(ident_service.usernameToId(editor_id), "com.k_int.aggregator.permission.edit");
		      for (int i=0; i<grants.length; i++) {
		        List<String> id_comps = grants[i].getIdentifierComponents();
		        if (id_comps.size()>0) {
		          Long coll_id             = new Long(id_comps.get(0));
		          AggregatorCollectionHDO coll = (AggregatorCollectionHDO) sess.get(AggregatorCollectionHDO.class,coll_id);
		          if (coll!=null) {
		            collections.put(coll.getId(), coll);
		          }
		        }
		      }
		    } catch (IdentityServiceException ise ) {
		    	log.error("Problem listing collections this user can edit ", ise);
		    }
		   
		    return collections;
	  }
	  
	  
	  
	  public static boolean canUserEditCollection(Session sess, IdentityService ident_service, String editor_id, String collectionCode) {

		  boolean returnValue = false;

		  if ( collectionCode != null && !"".equals(collectionCode.trim()) ) {
			  Map<Long,AggregatorCollectionHDO> collections = getValidCollectionsForEditor(sess, ident_service, editor_id);
		  
		  
			  if ( collections != null ) {
				  Set<Long> keyset = collections.keySet();
				  Iterator<Long> keysetIter = keyset.iterator();
				  while(keysetIter.hasNext()) {
					  Long key = keysetIter.next();
					  AggregatorCollectionHDO coll = collections.get(key);
					  if ( coll != null ) {
						  if ( collectionCode.trim().equals(coll.getCollectionCode().trim()) ) {
							  returnValue = true;
							  break;
						  }
					  }
				  }
			  }
		  }
		  
		  return returnValue;
	  }

}
