package eu.dnetlib.enabling.aas.admin;

import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.log4j.Logger;

import eu.dnetlib.enabling.aas.ctx.SecurityContextContainerException;
import eu.dnetlib.enabling.aas.is.ISConstants;
import eu.dnetlib.enabling.aas.is.ISUtils;
import eu.dnetlib.enabling.aas.service.A2Constants;
import eu.dnetlib.enabling.aas.service.A2Exception;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;

/**
 * Implements AdministrationService functionalities.
 * @author mhorst
 *
 */
public class GeneralAdministrationService implements IAdministrationService {

	ISLookUpService lookUpService;
	
	ResultSetService resultSetService;
	
	ISecurityContextContainerAdministration secCtxContainerAdm;
	
	ISecurityProfileProviderAdministration secProfProviderAdm;
	
	Set<ISecurityPolicyFMAdministration> secPolicyFMAdmSet;
	
	protected static final Logger log = Logger.getLogger(GeneralAdministrationService.class);
	
	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.admin.IAdministrationService#dropSecCtxs()
	 */
	public void dropSecCtxs() throws A2Exception {
		try {
			secCtxContainerAdm.dropAllSecCtxs();
		} catch (SecurityContextContainerException e) {
			throw new A2Exception("Exception occured when trying to delete all security contexts!",e);
		}
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.admin.IAdministrationService#dumpBufferedSecCtxs(java.io.OutputStream)
	 */
	public void dumpBufferedSecCtxs(OutputStream out) throws A2Exception {
		try {
			secCtxContainerAdm.dumpBufferedSecCtxs(out);
		} catch (SecurityContextContainerException e) {
			throw new A2Exception("Exception occured when trying to dump all security contexts!",e);
		}
	}


	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.admin.IAdministrationService#dumpISSecCtxs(java.io.OutputStream)
	 */
	public void dumpISSecCtxs(OutputStream out) throws A2Exception {
		PrintStream output = new PrintStream(out);
		W3CEndpointReference rsIdXml = null;
		try {
			rsIdXml = lookUpService.listResourceProfiles(A2Constants.RESOURCE_KIND_SECURITY_CONTEXT, 
					null, A2Constants.RESOURCE_TYPE_SECURITY_CONTEXT);
		} catch (ISLookUpException e) {
			throw new A2Exception("Exception occured when listing security contexts from IS!",e);
		}

		List<String> array1Res = null;
		try {
			String rsId = ISUtils.extractResultSetId(rsIdXml);

			if (rsId==null)
				return;
			int resultsCount = resultSetService.getNumberOfElements(rsId);
			array1Res = resultSetService.getResult(rsId, ISConstants.RESULT_SET_FIRST_ELEMENT, 
					resultsCount, ISConstants.RESULT_SET_REQUEST_MODE_WAITING);
		} catch (ResultSetException e) {
			throw new A2Exception("Exception occured when retrieving results from result service!",e);
		} 
		if (array1Res==null)
			return;
		else {
			Iterator<String> it = array1Res.iterator();
			while (it.hasNext()) {
				output.println(it.next());
			}
		}
	}


	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.admin.IAdministrationService#dumpPolicies(java.io.OutputStream)
	 */
	public void dumpPolicies(OutputStream out) {
		Iterator<ISecurityPolicyFMAdministration> it = secPolicyFMAdmSet.iterator();
		while (it.hasNext()) {
			ISecurityPolicyFMAdministration currentPolicyAdm = it.next();
			PrintWriter pw = new PrintWriter(out);
			pw.println("=====================================================================");
			pw.println("Current policy module: "+currentPolicyAdm.toString());
			pw.println("=====================================================================");
			currentPolicyAdm.dumpPolicies(out);
		}
	}
	

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.admin.IAdministrationService#dumpSecProfs(java.io.OutputStream)
	 */
	public void dumpSecProfs(OutputStream out) throws A2Exception {
		secProfProviderAdm.dumpSecProfs(out);
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.admin.IAdministrationService#invalidatePolicies()
	 */
	public void invalidatePolicies() {
		Iterator<ISecurityPolicyFMAdministration> it = secPolicyFMAdmSet.iterator();
		while (it.hasNext()) {
			ISecurityPolicyFMAdministration currentPolicyAdm = it.next();
			currentPolicyAdm.invalidateCache();
		}
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.admin.IAdministrationService#invalidateSecCtxs()
	 */
	public void invalidateSecCtxs() {
		secCtxContainerAdm.invalidateCache();
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.admin.IAdministrationService#invalidateSecProfs()
	 */
	public void invalidateSecProfs() {
		secProfProviderAdm.invalidateCache();
	}

	/**
	 * Returns Security Contexts administration module.
	 * @return Security Contexts administration module
	 */
	public ISecurityContextContainerAdministration getSecCtxContainerAdm() {
		return secCtxContainerAdm;
	}

	/**
	 * Sets Security Contexts administration module.
	 * @param secCtxContainerAdm
	 */
	public void setSecCtxContainerAdm(
			ISecurityContextContainerAdministration secCtxContainerAdm) {
		this.secCtxContainerAdm = secCtxContainerAdm;
	}

	/**
	 * Returns Security Profiles administration module.
	 * @return Security Profiles administration module
	 */
	public ISecurityProfileProviderAdministration getSecProfProviderAdm() {
		return secProfProviderAdm;
	}

	/**
	 * Sets Security Profiles administration module.
	 * @param secProfProviderAdm
	 */
	public void setSecProfProviderAdm(
			ISecurityProfileProviderAdministration secProfProviderAdm) {
		this.secProfProviderAdm = secProfProviderAdm;
	}

	/**
	 * Returns Security Policies administration modules.
	 * @return Security Policies administration modules
	 */
	public Set<ISecurityPolicyFMAdministration> getSecPolicyFMAdmSet() {
		return secPolicyFMAdmSet;
	}

	/**
	 * Sets Security Policies administration modules.
	 * @param secPolicyFMAdmList
	 */
	public void setSecPolicyFMAdmSet(
			Set<ISecurityPolicyFMAdministration> secPolicyFMAdmSet) {
		this.secPolicyFMAdmSet = secPolicyFMAdmSet;
	}

	/**
	 * Returns IS LookUp service.
	 * @return IS LookUp service
	 */
	public ISLookUpService getLookUpService() {
		return lookUpService;
	}

	/**
	 * Sets IS LookUp service.
	 * @param lookUpService
	 */
	public void setLookUpService(ISLookUpService lookUpService) {
		this.lookUpService = lookUpService;
	}

	/**
	 * Returns ResultSet service.
	 * @return ResultSet service
	 */
	public ResultSetService getResultSetService() {
		return resultSetService;
	}

	/**
	 * Sets ResultSet service.
	 * @param resultSetService
	 */
	public void setResultSetService(ResultSetService resultSetService) {
		this.resultSetService = resultSetService;
	}


}
