/*
 * Copyright 2001-2004 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.ws.secpolicy12.builders;

import java.util.Iterator;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.neethi.Assertion;
import org.apache.neethi.AssertionBuilderFactory;
import org.apache.neethi.Constants;
import org.apache.neethi.Policy;
import org.apache.neethi.PolicyEngine;
import org.apache.neethi.builders.AssertionBuilder;
import org.apache.ws.secpolicy.SPConstants;
import org.apache.ws.secpolicy.SP12Constants;
import org.apache.ws.secpolicy.model.X509Token;

public class X509TokenBuilder implements AssertionBuilder<OMElement> {
	
    public final static String USER_CERT_ALIAS_LN = "userCertAlias";

    public final static String ENCRYPTION_USER_LN = "encryptionUser";

    public static final QName RAMPART_CONFIG = new QName("http://ws.apache.org/rampart/policy",
            "RampartConfig");

    public static final QName USER_CERT_ALIAS = new QName("http://ws.apache.org/rampart/policy",
            USER_CERT_ALIAS_LN);

    public static final QName ENCRYPTION_USER = new QName("http://ws.apache.org/rampart/policy",
            ENCRYPTION_USER_LN);

    public Assertion build(OMElement element, AssertionBuilderFactory factory)
            throws IllegalArgumentException {
        X509Token x509Token = new X509Token(SPConstants.SP_V12);

        OMElement policyElement = element.getFirstElement();
        
        //Process token inclusion
        OMAttribute  includeAttr = element.getAttribute(SP12Constants.INCLUDE_TOKEN);
        if(includeAttr != null) {
            int inclusion = SP12Constants.getInclusionFromAttributeValue(includeAttr.getAttributeValue());
            x509Token.setInclusion(inclusion);
        }
        
        OMAttribute isOptional = element.getAttribute(Constants.Q_ELEM_OPTIONAL_ATTR);
		if (isOptional != null) {
			x509Token.setOptional(Boolean.valueOf(isOptional.getAttributeValue())
					.booleanValue());
		}

        if (policyElement != null) {
            
            if (policyElement.getFirstChildWithName(SP12Constants.REQUIRE_DERIVED_KEYS) != null) {
                x509Token.setDerivedKeys(true);
            } else if (policyElement.getFirstChildWithName(SP12Constants.REQUIRE_IMPLIED_DERIVED_KEYS) != null) {
                x509Token.setImpliedDerivedKeys(true);
            } else if (policyElement.getFirstChildWithName(SP12Constants.REQUIRE_EXPLICIT_DERIVED_KEYS) != null) {
                x509Token.setExplicitDerivedKeys(true);
            }
            
            Policy policy = PolicyEngine.getPolicy(element.getFirstElement());
            policy = (Policy) policy.normalize(false);

            for (Iterator<List<Assertion>> iterator = policy.getAlternatives(); iterator
                    .hasNext();) {
                processAlternative(iterator.next(), x509Token);
                
                /*
                 * since there should be only one alternative
                 */
                break;
            }
        }
        
        if (x509Token != null && policyElement != null) {
            OMElement ramp = null;
            ramp = policyElement.getFirstChildWithName(RAMPART_CONFIG);
            if (ramp != null) {
                OMElement child = null;
                if ((child = ramp.getFirstChildWithName(USER_CERT_ALIAS)) != null) {
                    x509Token.setUserCertAlias(child.getText());
                }
                if ((child = ramp.getFirstChildWithName(ENCRYPTION_USER)) != null) {
                    x509Token.setEncryptionUser(child.getText());
                }
            }
        }
        
        return x509Token;
    }

    private void processAlternative(List<Assertion> assertions, X509Token parent) {
                Assertion assertion;
        QName name;

        for (Iterator<Assertion> iterator = assertions.iterator(); iterator.hasNext();) {
            assertion = iterator.next();
            name = assertion.getName();

            if (SP12Constants.REQUIRE_KEY_IDENTIFIRE_REFERENCE.equals(name)) {
                parent.setRequireKeyIdentifierReference(true);

            } else if (SP12Constants.REQUIRE_ISSUER_SERIAL_REFERENCE.equals(name)) {
                parent.setRequireIssuerSerialReference(true);

            } else if (SP12Constants.REQUIRE_EMBEDDED_TOKEN_REFERENCE.equals(name)) {
                parent.setRequireEmbeddedTokenReference(true);

            } else if (SP12Constants.REQUIRE_THUMBPRINT_REFERENCE.equals(name)) {
                parent.setRequireThumbprintReference(true);

            } else if (SP12Constants.WSS_X509_V1_TOKEN_10.equals(name)) {
                parent.setTokenVersionAndType(SPConstants.WSS_X509_V1_TOKEN10);

            } else if (SP12Constants.WSS_X509_V1_TOKEN_11.equals(name)) {
                parent.setTokenVersionAndType(SPConstants.WSS_X509_V1_TOKEN11);

            } else if (SP12Constants.WSS_X509_V3_TOKEN_10.equals(name)) {
                parent.setTokenVersionAndType(SPConstants.WSS_X509_V3_TOKEN10);

            } else if (SP12Constants.WSS_X509_V3_TOKEN_11.equals(name)) {
                parent.setTokenVersionAndType(SPConstants.WSS_X509_V3_TOKEN11);

            } else if (SP12Constants.WSS_X509_PKCS7_TOKEN_10.equals(name)) {
                parent.setTokenVersionAndType(SPConstants.WSS_X509_PKCS7_TOKEN10);
                
            } else if (SP12Constants.WSS_X509_PKCS7_TOKEN_11.equals(name)) {
                parent.setTokenVersionAndType(SPConstants.WSS_X509_PKCS7_TOKEN11);
                
            } else if (SP12Constants.WSS_X509_PKI_PATH_V1_TOKEN_10.equals(name)) {
                parent.setTokenVersionAndType(SPConstants.WSS_X509_PKI_PATH_V1_TOKEN10);
                
            } else if (SP12Constants.WSS_X509_PKI_PATH_V1_TOKEN_11.equals(name)) {
                parent.setTokenVersionAndType(SPConstants.WSS_X509_PKI_PATH_V1_TOKEN11);
                
            }
        }
    }

    public QName[] getKnownElements() {
        return new QName[] {SP12Constants.X509_TOKEN};
    }
}
