/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2004
//
// Copyright in this library belongs to the IT Innovation Centre of
// 2 Venture Road, Chilworth Science Park, Southampton, SO16 7NP, UK.
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//      Created by:             Darren Marvin
//      Created date:           2003/09/19
//      Created for project:    GEMSS
//
/////////////////////////////////////////////////////////////////////////
//
//      Dependencies: None
//
/////////////////////////////////////////////////////////////////////////
//
//      Last commit info:       $Author: $
//                              $Date: $
//                              $Revision: $
//
/////////////////////////////////////////////////////////////////////////

package uk.ac.soton.itinnovation.gemss.transportmessaging.proxies.gemss;


import eu.gemss.*;
import eu.gemss.components.*;
import eu.gemss.components.security.*;
import eu.gemss.components.security.token.*;
import java.util.logging.*;
import uk.ac.soton.itinnovation.gemss.transportmessaging.configuration.*;
import uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.context.*;

public class GEMSSSecurityContext implements SecurityContext {

    private static Logger mLogger = Logger.getLogger("uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.context.GEMSSSecurityContext");

    /**
     * Set the configuration
     * @param config
     */
    public void initialise(TransportMessagingConfiguration config) {
        //doesn't need to do anything at mo
    }

    public SecurityToken generateSecurityToken(TokenDescriptor type) throws MessageContextException {
        try{
            if(type==null) {
                mLogger.log(Level.SEVERE,"Could not obtain security token, type specified is null");
                throw new MessageContextException("Could not obtain security token, likely bug please send a bug report including all log files");
            }
            //get the prevailing component manager
            ComponentManager cManager = null;
            cManager = GEMSS.getInstance();

            //get the security context module
            eu.gemss.components.security.GEMSSSecurityContext secCtx = (eu.gemss.components.security.GEMSSSecurityContext) cManager.getInstance("eu.gemss.components.security.GEMSSSecurityContext");
            return secCtx.generateSecurityToken(type);
        }
        catch(GridException ex) {
            //from different component so log it
            mLogger.log(Level.SEVERE,"Unable to obtain a security token described as '" + type.getDescription() + "' from security context component",ex);
            throw new MessageContextException("Unable to obtain a security token described as '" + type.getDescription() + "' from security context component");
        }

    }

    /**
     * Test to see if the passed security token is trusted in the prevailing security context
     * @param token
     * @return
     * @throws MessageContextException
     */
    public boolean isTrusted(SecurityToken token) throws MessageContextException {

        try{
            //get the prevailing component manager
           ComponentManager cManager = null;
           cManager = GEMSS.getInstance();
            //get the security context module
            //following needs fixing since it assume my provider, this is to get over missing method in nec api
	     eu.gemss.components.security.GEMSSSecurityContext secCtx = (eu.gemss.components.security.GEMSSSecurityContext) cManager.getInstance("eu.gemss.components.security.GEMSSSecurityContext");
//         uk.ac.soton.itinnovation.gemss.security.context.proxies.gemss.GEMSSSecurityContextComponent secCtx = (uk.ac.soton.itinnovation.gemss.security.context.proxies.gemss.GEMSSSecurityContextComponent) cManager.getNewInstance("eu.gemss.components.security.GEMSSSecurityContext");

            return secCtx.isTrusted(token);
        }
        catch(GridException ex) {
            try{
                //from difference component so log it
                mLogger.log(Level.SEVERE,"Unable to establish trust for a security token described as '" + token.getTokenDescriptor().getDescription() + "' from security context component",ex);
                throw new MessageContextException("Unable to establish trust for a security token described as '" + token.getTokenDescriptor().getDescription() + "' from security context component");
           }
           catch(eu.gemss.components.security.token.SecurityTokenException ex2) {
               //did our best
               throw new MessageContextException("Unable to establish trust for a security token from security context component");
           }
        }
    }

    /**
     * Add a security token instance to the prevailing security context
     * @param secToken security token to add
     * @throws MessageContextException
     */
    public void addSecurityTokenToContext(SecurityToken token) throws MessageContextException {
        try{
          //get the prevailing component manager
         ComponentManager cManager = null;
         cManager = GEMSS.getInstance();
         eu.gemss.components.security.GEMSSSecurityContext secCtx = (eu.gemss.components.security.GEMSSSecurityContext) cManager.getInstance("eu.gemss.components.security.GEMSSSecurityContext");
         secCtx.addSecurityTokenToContext(token);
        }
        catch(GridException ex) {
            try{
                //from difference component so log it
                mLogger.log(Level.SEVERE,"Unable to add security token described as '" + token.getTokenDescriptor().getDescription() + "' from security context component",ex);
                throw new MessageContextException("Unable to add security token described as '" + token.getTokenDescriptor().getDescription() + "' from security context component");
           }
           catch(eu.gemss.components.security.token.SecurityTokenException ex2) {
               //did our best
               throw new MessageContextException("Unable to add security token from security context component");
           }
        }
    }

    /**
     * Remove from the prevailing security context the security token identified by the supplied token descriptor
     * @param secToken token to remove
     * @throws MessageContextException
     */
    public void removeSecurityTokenFromContext(SecurityToken token) throws MessageContextException {
      try{
        //get the prevailing component manager
       ComponentManager cManager = null;
       cManager = GEMSS.getInstance();
       eu.gemss.components.security.GEMSSSecurityContext secCtx = (eu.gemss.components.security.GEMSSSecurityContext) cManager.getInstance("eu.gemss.components.security.GEMSSSecurityContext");
       secCtx.removeSecurityTokenFromContext(token);
      }
      catch(GridException ex) {
          try{
              //from difference component so log it
              mLogger.log(Level.SEVERE,"Unable to remove security token described as '" + token.getTokenDescriptor().getDescription() + "' from security context component",ex);
              throw new MessageContextException("Unable to remove security token described as '" + token.getTokenDescriptor().getDescription() + "' from security context component");
         }
         catch(eu.gemss.components.security.token.SecurityTokenException ex2) {
             //did our best
             throw new MessageContextException("Unable to add remove token from security context component");
         }
        }
    }

    /**
     * Retrieve from the prevailing security context a previously stored security token matching the passed token descriptor
     * @param tokenDesc token identifier
     * @return security token required
     * @throws MessageContextException
     */
    public SecurityToken getSecurityTokenFromContext(TokenDescriptor tokenDesc) throws MessageContextException {
      try{
        //get the prevailing component manager
       ComponentManager cManager = null;
       cManager = GEMSS.getInstance();
       eu.gemss.components.security.GEMSSSecurityContext secCtx = (eu.gemss.components.security.GEMSSSecurityContext) cManager.getInstance("eu.gemss.components.security.GEMSSSecurityContext");
       return secCtx.getSecurityToken(tokenDesc);
      }
      catch(GridException ex) {
              //from difference component so log it
              mLogger.log(Level.SEVERE,"Unable to add security token described as '" + tokenDesc.getDescription() + "' from security context component",ex);
              throw new MessageContextException("Unable to add security token described as '" + tokenDesc.getDescription() + "' from security context component");

        }
    }
}