package gov.va.med.authentication.kernel.ccow;

import gov.va.med.authentication.kernel.KaajeeException;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.log4j.Level;

import com.sentillion.sdkweb.webcontextor.ContextItem;
import com.sentillion.sdkweb.webcontextor.ContextItemCollection;
import com.sentillion.sdkweb.webcontextor.WebContextor;
import com.sentillion.sdkweb.webcontextor.WebContextorException;

/**
 * @author VHIT Security and Other Common Services (S&OCS)
 * @version 1.1.0.007
 */
public class CommonContextSession implements Serializable {
	
	private static Logger logger = Logger.getLogger(CommonContextSession.class);
	
	private String contextorBlobString = null;
	
	CommonContextSession(String contextorBlobString){
		this.contextorBlobString = contextorBlobString;
	}

	public ContextItemCollection getCurrentContext() {
		
		ContextItemCollection contextItemCollection = null;
		WebContextor webContextor = new WebContextor();		
	  	String [] contextorBlob = new String[1];	
		if (getState() != WebContextor.CsNotRunning){
		  	contextorBlob[0] = this.contextorBlobString;
			try {
				contextItemCollection = webContextor.getCurrentContext( contextorBlob);
			} catch (WebContextorException e1) {
				if (logger.isEnabledFor(Level.ERROR)) {
					logger.debug("in getCurrentContext: error in getting current context: " + e1);
				}
			} finally {
				this.contextorBlobString = contextorBlob[0];
			}
		} else {
			if (logger.isEnabledFor(Level.DEBUG)) {
				logger.debug("in getCurrentContext: contextor is not running: ");
			}
		}
		return contextItemCollection;
	}

	public void setContext(Map newContext) 
	throws KaajeeException {
		WebContextor contextor = new WebContextor();
		String [] contextorBlob = new String[1];
		contextorBlob[0] = this.contextorBlobString;
        try
        {
            contextor.startContextChange( contextorBlob);
            
            ContextItemCollection collection = new ContextItemCollection();
            String value = "";
            Set newItems = newContext.keySet();
            Iterator it = newItems.iterator();
            while (it.hasNext()){
            	String key = (String) it.next();
            	ContextItem item = new ContextItem();                
                item.setName(key);
                value = (String) newContext.get(key);
                item.setValue(value);
                collection.add(item);
                
    			if (logger.isEnabledFor(Level.DEBUG)) {
    				logger.debug("adding item: "
        					+ key + ":" + value
        					+ "\n");
    			}
            }
            String [] responses = null;
            boolean [] notContinue = new boolean[1];
            responses = contextor.endContextChange(contextorBlob,
            										true, 
            										collection,
            										notContinue);
            //boolean shouldCommit = responses.length > 0;
            boolean shouldCommit = true;
            String listeners = null;
            String [] coupon = new String [1]; 
            if (shouldCommit){
            	listeners = contextor.commitContextChange(contextorBlob, coupon);
            } else {
            	contextor.cancelContextChange(contextorBlob);
            }
            
			if (logger.isEnabledFor(Level.DEBUG)) {
				logger.debug("\n SET CONTEXT results :" 
						+ responses + "\n" 
						+ responses.length + "\n" 
						+ notContinue[0] + "\n"
						+ coupon[0] + "\n"
						+ listeners + "\n");
			}        
        }
        catch ( WebContextorException e)
        {
			if (logger.isEnabledFor(Level.ERROR)) {
				logger.debug("Failed to write new user context to vault: " + e);
			}
        	throw new KaajeeException("Failed to write new user context to vault");
        } finally {
        	this.contextorBlobString = contextorBlob[0];
        }

	}
	
/*	public static int getPrivilege (String subject, CcowEnv ccowSession) {
		
		int privilege = WebContextor.ApNone;
		WebContextor contextor = new WebContextor();
		String [] contextorBlob = new String[1];
		contextorBlob[0] = ccowSession.getBlob();
		try {
			privilege = contextor.getPrivilege(contextorBlob, subject);
		} catch (BadContextBlobException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidActionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadSubjectNameException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NonsecureParticipantException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownSubjectException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (WebContextorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return privilege;
	}*/
	
	public void stop () {
		
		WebContextor contextor = new WebContextor();
		
		if (getState() != WebContextor.CsNotRunning){
			String [] contextorBlob = new String[1];
			contextorBlob[0] = this.contextorBlobString;
			try {
				contextor.stop(contextorBlob);
			} catch (WebContextorException e) {
				if (logger.isEnabledFor(Level.ERROR)) {
					logger.debug("error in trying to stop context session: " + e);
				}
			} finally {
				this.contextorBlobString = contextorBlob[0];
			}
		} else {
			if (logger.isEnabledFor(Level.DEBUG)) {
				logger.debug("in context session stop: contextor is not running");
			}
		}
	}
	
	public void resume() {
		
		WebContextor contextor = new WebContextor();
		String [] contextorBlob = new String[1];
		contextorBlob[0] = this.contextorBlobString;
		if (getState() != WebContextor.CsParticipating){
			try {
				contextor.resume(contextorBlob);
			} catch (WebContextorException e) {
				if (logger.isEnabledFor(Level.ERROR)) {
					logger.debug("error in trying to resume context session: ");
					logger.debug("the state of the session is " + getState());
					logger.debug("the error was " + e);
				}
			} finally {
				this.contextorBlobString = contextorBlob[0];
			}
		} else {
			if (logger.isEnabledFor(Level.DEBUG)) {
				logger.debug("in resume context session: session is already participating");
			}
		}
	}
	
	public void suspend() {
		
		WebContextor contextor = new WebContextor();
		String [] contextorBlob = new String[1];
		contextorBlob[0] = this.contextorBlobString;
		if (getState() == WebContextor.CsParticipating){
			try {
				contextor.suspend(contextorBlob);
			} catch (WebContextorException e) {
				if (logger.isEnabledFor(Level.ERROR)) {
					logger.debug("error in trying to suspend context session: " + e);
				}
			} finally {
				this.contextorBlobString = contextorBlob[0];
			}
		} else {
			if (logger.isEnabledFor(Level.DEBUG)) {
				logger.debug("in suspend context: not participating");
			}
		}
	}

	
	public int getState () {
		int status = WebContextor.CsNotRunning;
		WebContextor contextor = new WebContextor();
		String [] contextorBlob = new String[1];
		contextorBlob[0] = this.contextorBlobString;
		try {
			status = contextor.getState(contextorBlob);
		} catch (WebContextorException e) {
			if (logger.isEnabledFor(Level.ERROR)) {
				logger.debug("error in trying to get state of context session: " + e);
			}
			status = WebContextor.CsNotRunning;
		} finally {
			this.contextorBlobString = contextorBlob[0];
			if (logger.isEnabledFor(Level.DEBUG)) {
				logger.debug("contextor status: " + status);
			}
		}
		return status;
	}

	public String getName() {
		String name = null;
		String [] contextorBlob = new String[1];
		contextorBlob[0] = this.contextorBlobString;
		WebContextor contextor = new WebContextor();
		try {
			name = contextor.getName(contextorBlob);
		} catch (WebContextorException e) {
			if (logger.isEnabledFor(Level.ERROR)) {
				logger.debug("error in trying to get name of context session: " + e);
			}
		} finally {
			this.contextorBlobString = contextorBlob[0];
		}
		return name;
	}

}
