/*
 * 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.AlgorithmSuite;
import org.apache.ws.secpolicy.model.SignedEncryptedElements;
import org.apache.ws.secpolicy.model.SignedEncryptedParts;
import org.apache.ws.secpolicy.model.SupportingToken;
import org.apache.ws.secpolicy.model.Token;

public class SupportingTokensBuilder implements AssertionBuilder<OMElement> {

    public Assertion build(OMElement element, AssertionBuilderFactory factory)
            throws IllegalArgumentException {
        QName name = element.getQName();
        SupportingToken supportingToken = null;

        if (SP12Constants.SUPPORTING_TOKENS.equals(name)) {
            supportingToken = new SupportingToken(
                    SPConstants.SUPPORTING_TOKEN_SUPPORTING, SPConstants.SP_V12);
        } else if (SP12Constants.SIGNED_SUPPORTING_TOKENS.equals(name)) {
            supportingToken = new SupportingToken(
                    SPConstants.SUPPORTING_TOKEN_SIGNED, SPConstants.SP_V12);
        } else if (SP12Constants.ENDORSING_SUPPORTING_TOKENS.equals(name)) {
            supportingToken = new SupportingToken(
                    SPConstants.SUPPORTING_TOKEN_ENDORSING, SPConstants.SP_V12);
        } else if (SP12Constants.SIGNED_ENDORSING_SUPPORTING_TOKENS.equals(name)) {
            supportingToken = new SupportingToken(
                    SPConstants.SUPPORTING_TOKEN_SIGNED_ENDORSING, SPConstants.SP_V12);
        } else if (SP12Constants.ENCRYPTED_SUPPORTING_TOKENS.equals(name)) {
            supportingToken = new SupportingToken(
                    SPConstants.SUPPORTING_TOKEN_ENCRYPTED, SPConstants.SP_V12);
        } else if (SP12Constants.SIGNED_ENCRYPTED_SUPPORTING_TOKENS.equals(name)) {
            supportingToken = new SupportingToken(
                    SPConstants.SUPPORTING_TOKEN_SIGNED_ENCRYPTED, SPConstants.SP_V12);            
        } else if (SP12Constants.ENDORSING_ENCRYPTED_SUPPORTING_TOKENS.equals(name)) {
            supportingToken = new SupportingToken(
                    SPConstants.SUPPORTING_TOKEN_ENDORSING_ENCRYPTED, SPConstants.SP_V12); 
        } else if (SP12Constants.SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS.equals(name)) {
            supportingToken = new SupportingToken(
                    SPConstants.SUPPORTING_TOKEN_SIGNED_ENDORSING_ENCRYPTED, SPConstants.SP_V12);             
        }
        
        OMAttribute isOptional = element.getAttribute(Constants.Q_ELEM_OPTIONAL_ATTR);
		if (isOptional != null) {
			supportingToken.setOptional(Boolean.valueOf(isOptional.getAttributeValue())
					.booleanValue());
		}

        Policy policy = PolicyEngine.getPolicy(element.getFirstElement());
        policy = (Policy) policy.normalize(false);

        for (Iterator<List<Assertion>> iterator = policy.getAlternatives(); iterator.hasNext();) {
            processAlternative(iterator.next(), supportingToken);
            /*
             * for the moment we will say there should be only one alternative 
             */
            break;            
        }

        return supportingToken;
    }

    public QName[] getKnownElements() {
        return new QName[] { SP12Constants.SUPPORTING_TOKENS,
                SP12Constants.SIGNED_SUPPORTING_TOKENS,
                SP12Constants.ENDORSING_SUPPORTING_TOKENS,
                SP12Constants.SIGNED_ENDORSING_SUPPORTING_TOKENS,
                SP12Constants.ENCRYPTED_SUPPORTING_TOKENS,
                SP12Constants.SIGNED_ENCRYPTED_SUPPORTING_TOKENS,
                SP12Constants.ENDORSING_ENCRYPTED_SUPPORTING_TOKENS,
                SP12Constants.SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS  
                };
    }

    private void processAlternative(List<Assertion> assertions, SupportingToken supportingToken) {
        
        for (Iterator<Assertion> iterator = assertions.iterator(); iterator.hasNext();) {

            Assertion primitive = iterator.next();
            QName qname = primitive.getName();

            if (SP12Constants.ALGORITHM_SUITE.equals(qname)) {
                supportingToken.setAlgorithmSuite((AlgorithmSuite) primitive);

            } else if (SP12Constants.SIGNED_PARTS.equals(qname)) {
                supportingToken
                        .setSignedParts((SignedEncryptedParts) primitive);

            } else if (SP12Constants.SIGNED_ELEMENTS.equals(qname)) {
                supportingToken
                        .setSignedElements((SignedEncryptedElements) primitive);

            } else if (SP12Constants.ENCRYPTED_PARTS.equals(qname)) {
                supportingToken
                        .setEncryptedParts((SignedEncryptedParts) primitive);

            } else if (SP12Constants.ENCRYPTED_ELEMENTS.equals(qname)) {
                supportingToken
                        .setEncryptedElements((SignedEncryptedElements) primitive);

            } else if (primitive instanceof Token) {
                supportingToken.addToken((Token) primitive);
            }
        }
    }
}
