/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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.directory.shared.ldap.extras.extended;


import javax.naming.NamingException;
import javax.naming.ldap.ExtendedResponse;

import org.apache.directory.shared.asn1.DecoderException;
import org.apache.directory.shared.asn1.EncoderException;
import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.extras.extended.ads_impl.CertGenerationDecoder;
import org.apache.directory.shared.ldap.extras.extended.ads_impl.CertGenerationObject;
import org.apache.directory.shared.ldap.model.message.ExtendedRequestImpl;
import org.apache.directory.shared.ldap.model.message.ResultResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 
 * An extended operation requesting the server to generate a public/private key pair and a certificate
 * and store them in a specified target entry in the DIT.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class CertGenerationRequest extends ExtendedRequestImpl
{
    /** The serial version UUID */
    private static final long serialVersionUID = 1L;

    private CertGenerationObject certGenObj;

    private static final Logger LOG = LoggerFactory.getLogger( CertGenerationRequest.class );

    public static final String EXTENSION_OID = "1.3.6.1.4.1.18060.0.1.8";


    /**
     * Creates a new instance of CertGenerationRequest.
     *
     * @param messageId the message id
     * @param targerDN the Dn of target entry whose key and certificate values will be changed
     * @param issuerDN Dn to be used as the issuer's Dn in the certificate
     * @param subjectDN Dn to be used as certificate's subject
     * @param keyAlgorithm crypto algorithm name to be used for generating the keys
     */
    public CertGenerationRequest( int messageId, String targerDN, String issuerDN, String subjectDN, String keyAlgorithm )
    {
        super( messageId );
        setRequestName( EXTENSION_OID );

        this.certGenObj = new CertGenerationObject();
        certGenObj.setTargetDN( targerDN );
        certGenObj.setIssuerDN( issuerDN );
        certGenObj.setSubjectDN( subjectDN );
        certGenObj.setKeyAlgorithm( keyAlgorithm );
    }


    /**
     * Creates a new instance of CertGenerationRequest.
     */
    public CertGenerationRequest()
    {
        setRequestName( EXTENSION_OID );
        this.certGenObj = new CertGenerationObject();
    }


    public void setequestValue( byte[] requestValue )
    {
        CertGenerationDecoder decoder = new CertGenerationDecoder();

        try
        {
            certGenObj = (CertGenerationObject) decoder.decode( requestValue );

            if ( requestValue != null )
            {
                this.requestValue = new byte[requestValue.length];
                System.arraycopy( requestValue, 0, this.requestValue, 0, requestValue.length );
            }
            else
            {
                this.requestValue = null;
            }
        }
        catch ( DecoderException e )
        {
            LOG.error( I18n.err( I18n.ERR_04165 ), e );
            throw new RuntimeException( e );
        }
    }


    public ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset, int length )
        throws NamingException
    {
        return ( ExtendedResponse ) getResultResponse();
    }


    /**
     * {@inheritDoc}
     */
    public byte[] getRequestValue()
    {
        if ( requestValue == null )
        {
            try
            {
                requestValue = certGenObj.encode().array();
            }
            catch ( EncoderException e )
            {
                LOG.error( I18n.err( I18n.ERR_04167 ), e );
                throw new RuntimeException( e );
            }
        }

        if ( requestValue == null )
        {
            return null;
        }

        final byte[] copy = new byte[requestValue.length];
        System.arraycopy( requestValue, 0, copy, 0, requestValue.length );
        return copy;
    }


    public ResultResponse getResultResponse()
    {
        if ( response == null )
        {
            response = new CertGenerationResponse( getMessageId() );
        }

        return response;
    }


    public String getTargetDN()
    {
        return certGenObj.getTargetDN();
    }


    public void setTargetDN( String targetDN )
    {
        certGenObj.setTargetDN( targetDN );
    }


    public String getIssuerDN()
    {
        return certGenObj.getIssuerDN();
    }


    public void setIssuerDN( String issuerDN )
    {
        certGenObj.setIssuerDN( issuerDN );
    }


    public String getSubjectDN()
    {
        return certGenObj.getSubjectDN();
    }


    public void setSubjectDN( String subjectDN )
    {
        certGenObj.setSubjectDN( subjectDN );
    }


    public String getKeyAlgorithm()
    {
        return certGenObj.getKeyAlgorithm();
    }


    public void setKeyAlgorithm( String keyAlgorithm )
    {
        certGenObj.setKeyAlgorithm( keyAlgorithm );
    }
}
