/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.rampart.conversation;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.description.Parameter;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.SimpleTokenStore;
import org.apache.rahas.TokenStorage;
import org.apache.rampart.RampartException;
import org.apache.rampart.handler.WSSHandlerConstants;
import org.apache.rampart.util.Axis2Util;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.apache.ws.security.message.token.SecurityContextToken;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;

import java.util.Hashtable;
import java.util.Properties;

/**
 * Configuration manager for Ramapart-SecConv
 * @deprecated
 */
public class ConversationConfiguration {
    
    public final static String SC_CONFIG = "sc-configuration";
    
    public final static String SCOPE_SERVICE = "service";
    
    public final static String SCOPE_OPERATION = "operation";

    public final static QName SCOPE = new QName("scope");
    
    public final static QName STS_EPR_ADDRESS = new QName("stsEprAddress");
    
    public final static QName DERIVED_KEY_LENGTH = new QName("derivedKeyLength");
    
    public final static QName KEY_DERIVATION_ALGORITHM_CLASS = 
                              new QName("keyDerivationAlgorithmClass");
    
    public final static QName TOKEN_STORE_CLASS = new QName("tokenStoreClass");
    
    public final static QName CRYPTO_PROPERTIES_FILE = new QName(
            "cryptoProperties");
    
    public final static QName ENCRYPTION_USER = new QName("encryptionUser");
    
    public final static QName PW_CALLBACK_CLASS = new QName(
            WSHandlerConstants.PW_CALLBACK_CLASS);

    private static final QName PROVIDE_ENTROPY = new QName("provideEntropy");
    
    private String scope = SCOPE_SERVICE;
    
    private String stsEPRAddress;
    
    private String derivedKeyLength;
    
    private String keyDerivationAlgorithmClass;
    
    private Hashtable contextMap;
    
    private String tokenStoreClass;
    
    private TokenStorage tokenStore;

    private MessageContext msgCtx;
    
    private String contextIdentifier;
    
    /**
     * This is the properties of a particular <code>Crypto</code> impl
     * 
     * @see org.apache.ws.security.components.crypto.Crypto
     */
    private Properties cryptoProperties;
    
    /**
     * This is the <code>Crypto</code> impl class name.
     * 
     * This will ONLY be set via the message context as a property using 
     * <code>org.apache.rampart.WSSHandlerConstants#CRYPTO_PROPERTIES_KEY<code>. 
     * 
     * @see org.apache.ws.security.components.crypto.Crypto
     * @see org.apache.ws.security.components.crypto.Merlin
     */
    private String cryptoClassName;
    
    /**
     * This is the crypto properties file to be used
     * In this case the <code>Crypto</code> impl and its properties 
     * MUST be listed in this
     * @see org.apache.ws.security.components.crypto.CryptoFactory#getInstance(String)
     */
    private String cryptoPropertiesFile;
    
    private String passwordCallbackClass;
    
    /**
     * WSPasswordCallback handler reference
     */
    private CallbackHandler passwordCallbackRef;
    
    /**
     * Whether this configuration instance is created/used by the sender 
     * handler or not
     */
    private boolean sender;
    
    private Document doc;
    
    private Crypto crypto;
    
    private ClassLoader classLoader;
    
    private SecurityContextToken sct;
    
    private String encryptionUser;
    
    private boolean provideEntropy;
    
    /**
     * WS-Trust version to use
     * Default is RahasConstants.VERSION_05_02
     */
    private int wstVersion = RahasConstants.VERSION_05_02;
    
    /**
     * Builds the configuration from an Axis2 parameter.
     * @param msgCtx
     * @param sender
     * @return If there is an Axis2 parameter available in the context
     * hierarchy or the configuration hierarchy then return the populated
     * <code>ConversationConfiguration</code> instance. If the parameter is not
     * found then  
     * @throws Exception
     */
    public static ConversationConfiguration load(MessageContext msgCtx, boolean sender)
            throws Exception {
        Parameter param = getParameter(msgCtx);
        if(param != null) {
            OMElement elem = param.getParameterElement();
            if (elem != null
                    && elem.getFirstElement() != null
                    && elem.getFirstElement().getLocalName().equals(
                            SC_CONFIG)) {
                
                OMElement confElem = elem.getFirstElement();
                
                ConversationConfiguration config = new ConversationConfiguration();
                
                config.msgCtx = msgCtx;
                msgCtx.setProperty(SC_CONFIG, config);
                
                config.scope = getStringValue(confElem.getFirstChildWithName(SCOPE));
                
                config.stsEPRAddress = getStringValue(confElem
                        .getFirstChildWithName(STS_EPR_ADDRESS));

                config.keyDerivationAlgorithmClass = getStringValue(confElem
                        .getFirstChildWithName(KEY_DERIVATION_ALGORITHM_CLASS));
                
                config.tokenStoreClass = getStringValue(confElem
                        .getFirstChildWithName(TOKEN_STORE_CLASS));
                
                config.cryptoPropertiesFile = getStringValue(confElem
                        .getFirstChildWithName(CRYPTO_PROPERTIES_FILE));

                config.passwordCallbackClass = getStringValue(confElem
                        .getFirstChildWithName(PW_CALLBACK_CLASS));
                
                config.encryptionUser = getStringValue(confElem
                        .getFirstChildWithName(ENCRYPTION_USER));
                
                config.provideEntropy = confElem
                        .getFirstChildWithName(PROVIDE_ENTROPY) != null;
                
                //Get the action<->ctx-identifier map
                config.contextMap = (Hashtable) msgCtx
                        .getProperty(WSSHandlerConstants.CONTEXT_MAP_KEY);

                //Convert the Envelop to DOOM
                config.doc = Axis2Util.getDocumentFromSOAPEnvelope(msgCtx
                        .getEnvelope(), true);
                
                //Token store
                config.tokenStore = (TokenStorage) msgCtx
                        .getProperty(TokenStorage.TOKEN_STORAGE_KEY);
    
                // Context identifier
                if(sender) {
                    if(!msgCtx.isServerSide()) {
                        //Client side sender
                        if (config.scope.equals(ConversationConfiguration.SCOPE_OPERATION)) {
                            // Operation scope
                            String action = msgCtx.getSoapAction();
                            config.contextIdentifier = (String) config.getContextMap()
                                    .get(action);
                        } else {
                            // Service scope
                            String serviceAddress = msgCtx.getTo().getAddress();
                            config.contextIdentifier = (String) config.getContextMap()
                                    .get(serviceAddress);
                        }
                        if(config.sct == null && config.contextIdentifier != null) {
                            OMElement tokElem = config.getTokenStore().getToken(config.contextIdentifier).getToken();
                            config.sct = new SecurityContextToken((Element)config.doc.importNode((Element)tokElem, true));
                        }
                        
                    } else {
                        //Server side sender
                        OperationContext opCtx = msgCtx.getOperationContext();
                        MessageContext inMsgCtx;
                        ConversationConfiguration inConfig = null;
                        if(opCtx != null && (inMsgCtx = opCtx.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE)) != null) {
                            inConfig = (ConversationConfiguration)inMsgCtx.getProperty(SC_CONFIG);
                        }
                        if(inConfig != null && inConfig.contextIdentifier != null) {
                            config.contextIdentifier = inConfig.contextIdentifier;
                            config.tokenStore = inConfig.tokenStore;
                            OMElement token = config.tokenStore.getToken(config.contextIdentifier).getToken();
                            config.sct = new SecurityContextToken((Element)config.doc.importNode((Element)token, true));
                        } else {
                            throw new RampartException("canotFindContextIdentifier");
                        }
                        
                        config.setClassLoader(msgCtx.getAxisService().getClassLoader());
                    }
                }

                //Crypto properties
                config.cryptoProperties = (Properties)msgCtx
                        .getProperty(WSSHandlerConstants.CRYPTO_PROPERTIES_KEY);

                config.cryptoClassName = (String) msgCtx
                        .getProperty(WSSHandlerConstants.CRYPTO_CLASS_KEY);
                
                config.passwordCallbackRef = (CallbackHandler)msgCtx
                        .getProperty(WSHandlerConstants.PW_CALLBACK_REF);
                
                config.sender = sender;
                
                return config;
            } else {
                throw new RampartException("missingConfiguration",
                        new String[] { SC_CONFIG });
            }
        } else {
            //If there's no configuration return null
            return null;
        }
        
    }

    /**
     * @param msgCtx
     * @return The configuration parameter from the given message context
     */
    public static Parameter getParameter(MessageContext msgCtx) {
        Parameter param = msgCtx.getParameter(SC_CONFIG);
        if(param == null) {
            param = (Parameter)msgCtx.getProperty(SC_CONFIG);
        }
        return param;
    }

    /**
     * @param elem
     * @throws RampartException
     */
    private static String getStringValue(OMElement elem) throws RampartException {
        if(elem != null) {
            return elem.getText();
        }
        return null;
    }

    /**
     * Generate the Axis2 parameter representing ConversationConfiguration
     * @return The Axis2 parameter representing ConversationConfiguration
     */
    public Parameter getParameter() {
        Parameter param = new Parameter();
        OMElement element = this.getOMElement();
        OMElement paramElem = element.getOMFactory().createOMElement("parameter", null);
        paramElem.addAttribute("name", ConversationConfiguration.SC_CONFIG, null);
        paramElem.addChild(element);
        param.setParameterElement(paramElem);
        return param;
    }
    
    private OMElement getOMElement() {
        OMFactory factory = OMAbstractFactory.getOMFactory();
        OMElement elem = factory.createOMElement(SC_CONFIG, null);
        if (this.scope != null) {
            OMElement tempElem = factory.createOMElement(SCOPE, elem);
            tempElem.setText(this.scope);
            elem.addChild(tempElem);
        }
        if (this.stsEPRAddress != null) {
            OMElement tempElem = factory.createOMElement(STS_EPR_ADDRESS, elem);
            tempElem.setText(this.stsEPRAddress);
            elem.addChild(tempElem);
        }
        if (this.derivedKeyLength != null) {
            OMElement tempElem = factory.createOMElement(DERIVED_KEY_LENGTH, elem);
            tempElem.setText(this.derivedKeyLength);
            elem.addChild(tempElem);
        }
        if (this.keyDerivationAlgorithmClass != null) {
            OMElement tempElem = factory.createOMElement(KEY_DERIVATION_ALGORITHM_CLASS, elem);
            tempElem.setText(this.keyDerivationAlgorithmClass);
            elem.addChild(tempElem);
        }
        if (this.passwordCallbackClass != null) {
            OMElement tempElem = factory.createOMElement(PW_CALLBACK_CLASS, elem);
            tempElem.setText(this.passwordCallbackClass);
            elem.addChild(tempElem);
        }
        if(this.cryptoPropertiesFile != null) {
            OMElement tempElem = factory.createOMElement(CRYPTO_PROPERTIES_FILE, elem);
            tempElem.setText(this.cryptoPropertiesFile);
            elem.addChild(tempElem);
        }
        if(this.encryptionUser != null) {
            OMElement tempElem = factory.createOMElement(ENCRYPTION_USER, elem);
            tempElem.setText(this.encryptionUser);
            elem.addChild(tempElem);
        }
        if(this.provideEntropy) {
            factory.createOMElement(PROVIDE_ENTROPY, elem);
        }
        return elem;
    }
    
//    /**
//     * This registers the security context mapping ?e context identifier to 
//     * the wsa:Action/soapAction or the service address, depending on the scope.
//     * 
//     * @param identifier The security context identifier
//     * @throws RampartException 
//     *      If scope is "operation" and the wsa:Action is not available.
//     *      If scope is "service" and the wsa:To is missing.  
//     */
//    protected void resgisterContext(String identifier) throws RampartException {
//        this.contextIdentifier = identifier;
//        
//        if(this.scope.equals(SCOPE_OPERATION)) {
//            String action = msgCtx.getSoapAction();
//            if(action != null) {
//                this.getContextMap().put(action, identifier);
//            } else {
//                throw new RampartException("missingWSAAction");
//            }
//        } else {
//            String to = msgCtx.getTo().getAddress();
//            if(to != null) {
//                this.getContextMap().put(to, identifier);
//            } else {
//                throw new RampartException("missingWSATo");
//            }
//        }
//        //TODO
//        //this.contextMap
//    }
    
    /**
     * @return Returns the scope.
     */
    public String getScope() {
        return scope;
    }

    /**
     * @return Returns the stsEPR.
     */
    public String getStsEPRAddress() {
        return stsEPRAddress;
    }

    /**
     * @return Returns the derivedKeyLength.
     */
    public String getDerivedKeyLength() {
        return derivedKeyLength;
    }

    /**
     * @return Returns the keyDerivationAlgorithmClass.
     */
    public String getKeyDerivationAlgorithmClass() {
        return keyDerivationAlgorithmClass;
    }

    /**
     * @param derivedKeyLength The derivedKeyLength to set.
     */
    public void setDerivedKeyLength(String derivedKeyLength) {
        this.derivedKeyLength = derivedKeyLength;
    }

    /**
     * @param keyDerivationAlgorithmClass The keyDerivationAlgorithmClass to set.
     */
    public void setKeyDerivationAlgorithmClass(String keyDerivationAlgorithmClass) {
        this.keyDerivationAlgorithmClass = keyDerivationAlgorithmClass;
    }

    /**
     * @param scope The scope to set.
     */
    public void setScope(String scope) {
        this.scope = scope;
    }

    /**
     * @param stsEPRAddress The stsEPRAddress to set.
     */
    public void setStsEPRAddress(String stsEPRAddress) {
        this.stsEPRAddress = stsEPRAddress;
    }

    /**
     * @return Returns the contextMap.
     */
    protected Hashtable getContextMap() {
        if(contextMap == null) {
            contextMap = new Hashtable();
            
            //Context map should be global
            this.msgCtx.getConfigurationContext().setProperty(
                    WSSHandlerConstants.CONTEXT_MAP_KEY, contextMap);
        }
        
        return contextMap;
    }

    /**
     * @return Returns the tokenStore.
     */
    public TokenStorage getTokenStore() throws Exception {
        if(this.tokenStore == null) {
            
            //First check the context hierarchy
            this.tokenStore = (TokenStorage) this.msgCtx
                    .getProperty(TokenStorage.TOKEN_STORAGE_KEY
                            + msgCtx.getWSAAction());
            if(this.tokenStore == null) {
                this.tokenStore = (TokenStorage) this.msgCtx
                .getProperty(TokenStorage.TOKEN_STORAGE_KEY
                        + msgCtx.getAxisService().getName()); 
            }
            
            //Create a new store
            if(this.tokenStore == null) {
                if(this.tokenStoreClass != null) {
                     this.tokenStore = (TokenStorage) Class
                            .forName(this.tokenStoreClass).newInstance();
                } else {
                    this.tokenStore = new SimpleTokenStore();
                }
            }
            
            if(SCOPE_SERVICE.equals(this.scope)) {
                this.msgCtx.getConfigurationContext().setProperty(
                        TokenStorage.TOKEN_STORAGE_KEY, this.tokenStore);
            } else {
                this.msgCtx.getConfigurationContext().setProperty(
                        TokenStorage.TOKEN_STORAGE_KEY, this.tokenStore);
            }
        }
        return tokenStore;
    }

    /**
     * @return Returns the tokenStoreClass.
     */
    public String getTokenStoreClass() {
        return tokenStoreClass;
    }


    /**
     * @return Returns the cryptoProperties.
     */
    public Properties getCryptoProperties() {
        return cryptoProperties;
    }

    /**
     * @param cryptoProperties The cryptoProperties to set.
     */
    public void setCryptoProperties(Properties cryptoProperties) {
        this.cryptoProperties = cryptoProperties;
    }

    /**
     * @param tokenStoreClass The tokenStoreClass to set.
     */
    public void setTokenStoreClass(String tokenStoreClass) {
        this.tokenStoreClass = tokenStoreClass;
    }

    /**
     * @return Returns the cryptoPropertiesFile.
     */
    public String getCryptoPropertiesFile() {
        return cryptoPropertiesFile;
    }

    /**
     * @param cryptoPropertiesFile The cryptoPropertiesFile to set.
     */
    public void setCryptoPropertiesFile(String cryptoPropertiesFile) {
        this.cryptoPropertiesFile = cryptoPropertiesFile;
    }

    /**
     * @return Returns the cryptoClassName.
     */
    public String getCryptoClassName() {
        return cryptoClassName;
    }

    /**
     * @param cryptoClassName The cryptoClassName to set.
     */
    public void setCryptoClassName(String cryptoClassName) {
        this.cryptoClassName = cryptoClassName;
    }

    /**
     * @return Returns the sender.
     */
    protected boolean isSender() {
        return sender;
    }

    /**
     * @return Returns the doc.
     */
    public Document getDocument() {
        return doc;
    }

    /**
     * @param doc The doc to set.
     */
    protected void setDocument(Document doc) {
        this.doc = doc;
    }

    /**
     * @return Returns the passwordCallbackClass.
     */
    public String getPasswordCallbackClass() {
        return passwordCallbackClass;
    }

    /**
     * @return Returns the passwordCallbackRef.
     */
    public CallbackHandler getPasswordCallbackRef() {
        return passwordCallbackRef;
    }

    /**
     * @param passwordCallbackClass The passwordCallbackClass to set.
     */
    public void setPasswordCallbackClass(String passwordCallbackClass) {
        this.passwordCallbackClass = passwordCallbackClass;
    }

    /**
     * @return Returns the encryptionUser.
     */
    public String getEncryptionUser() {
        return encryptionUser;
    }

    /**
     * @param encryptionUser The encryptionUser to set.
     */
    public void setEncryptionUser(String encryptionUser) {
        this.encryptionUser = encryptionUser;
    }

    /**
     * @return Returns the provideEntropy.
     */
    public boolean isProvideEntropy() {
        return provideEntropy;
    }

    /**
     * @param provideEntropy The provideEntropy to set.
     */
    public void setProvideEntropy(boolean provideEntropy) {
        this.provideEntropy = provideEntropy;
    }

    /**
     * @return Returns the crypto.
     */
    public Crypto getCrypto() {
        return crypto;
    }

    /**
     * @param crypto The crypto to set.
     */
    protected void setCrypto(Crypto crypto) {
        this.crypto = crypto;
    }

    /**
     * @return Returns the classLoader.
     */
    protected ClassLoader getClassLoader() {
        return classLoader;
    }

    /**
     * @param classLoader The classLoader to set.
     */
    protected void setClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    /**
     * @return Returns the msgCtx.
     */
    public MessageContext getMsgCtx() {
        return msgCtx;
    }
    
    /**
     * @return Returns the contextIdentifier.
     */
    public String getContextIdentifier() {
        return contextIdentifier;
    }

    /**
     * @param contextIdentifier The contextIdentifier to set.
     */
    protected void setContextIdentifier(String contextIdentifier) {
        this.contextIdentifier = contextIdentifier;
    }

    /**
     * @return Returns the wstVersion.
     */
    public int getWstVersion() {
        return wstVersion;
    }

    /**
     * @param wstVersion The wstVersion to set.
     */
    public void setWstVersion(int wstVersion) {
        this.wstVersion = wstVersion;
    }
}
