/*
 * 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.rahas.impl;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.rahas.TrustException;

import javax.xml.namespace.QName;

import java.io.FileInputStream;

/**
 * SCTIssuer Configuration processor
 */
public class SCTIssuerConfig extends AbstractIssuerConfig{

    public final static QName SCT_ISSUER_CONFIG = new QName("sct-issuer-config");
    protected byte[] requesterEntropy;

    private SCTIssuerConfig(OMElement elem) throws TrustException {
        OMElement proofKeyElem = elem.getFirstChildWithName(PROOF_KEY_TYPE);
        if (proofKeyElem != null) {
            this.proofKeyType = proofKeyElem.getText().trim();
        }

        OMElement cryptoPropertiesElem = elem
                .getFirstChildWithName(new QName("cryptoProperties"));

        if (!TokenIssuerUtil.BINARY_SECRET.equals(proofKeyType) && cryptoPropertiesElem == null) {
            throw new TrustException("sctIssuerCryptoPropertiesMissing");
        }

        this.addRequestedAttachedRef =
                elem.getFirstChildWithName(ADD_REQUESTED_ATTACHED_REF) != null;
        this.addRequestedUnattachedRef =
                elem.getFirstChildWithName(ADD_REQUESTED_UNATTACHED_REF) != null;
        if ((cryptoElement =
                cryptoPropertiesElem.getFirstChildWithName(CRYPTO)) == null) { // no children. Hence, prop file should have been defined
            this.cryptoPropertiesFile = cryptoPropertiesElem.getText().trim();
        }
        // else Props should be defined as children of a crypto element
        
        OMElement keyCompElem = elem.getFirstChildWithName(KeyComputation.KEY_COMPUTATION);
        if (keyCompElem != null && keyCompElem.getText() != null && !"".equals(keyCompElem.getText())) {
            this.keyComputation = Integer.parseInt(keyCompElem.getText());
        }
    }

    public static SCTIssuerConfig load(OMElement elem) throws TrustException {
        return new SCTIssuerConfig(elem);
    }

    public static SCTIssuerConfig load(String configFilePath)
            throws TrustException {
        FileInputStream fis;
        OMXMLParserWrapper builder;
        try {
            fis = new FileInputStream(configFilePath);
            builder = OMXMLBuilderFactory.createOMBuilder(fis);
        } catch (Exception e) {
            throw new TrustException("errorLoadingConfigFile",
                    new String[] { configFilePath });
        }

        return load(builder.getDocumentElement());
    }
}