/*
 *  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 java.nio.ByteBuffer;
import java.util.List;

import org.apache.directory.shared.asn1.DecoderException;
import org.apache.directory.shared.asn1.EncoderException;
import org.apache.directory.shared.asn1.ber.Asn1Decoder;
import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.extras.extended.ads_impl.GracefulDisconnectContainer;
import org.apache.directory.shared.ldap.extras.extended.ads_impl.GracefulDisconnectDecoder;
import org.apache.directory.shared.ldap.model.exception.LdapURLEncodingException;
import org.apache.directory.shared.ldap.model.message.ExtendedResponseImpl;
import org.apache.directory.shared.ldap.model.message.Referral;
import org.apache.directory.shared.ldap.model.message.ReferralImpl;
import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
import org.apache.directory.shared.ldap.model.filter.LdapURL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * An unsolicited notification, extended response, intended for notifying
 * clients of upcoming disconnection due to intended service windows. Unlike the
 * {@link org.apache.directory.shared.ldap.model.message.extended.NoticeOfDisconnect} this response contains additional information about
 * the amount of time the server will be offline and exactly when it intends to
 * shutdown.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class GracefulDisconnect extends ExtendedResponseImpl
{
    /** The serialVersionUID. */
    private static final long serialVersionUID = -4682291068700593492L;

    /** The OID for the graceful disconnect extended operation response. */
    public static final String EXTENSION_OID = "1.3.6.1.4.1.18060.0.1.5";

    /** The logger. */
    private static final Logger LOG = LoggerFactory.getLogger( GracefulDisconnect.class );

    /** Offline time after disconnection */
    private int timeOffline;

    /** Delay before disconnection */
    private int delay;

    /** String based LDAP URL that may be followed for replicated namingContexts */
    private Referral replicatedContexts = new ReferralImpl();


    /**
     * Instantiates a new graceful disconnect.
     *
     * @param responseValue the response value
     * @throws DecoderException if the response value can't be decoded
     */
    public GracefulDisconnect( byte[] responseValue ) throws DecoderException
    {
        super( 0, EXTENSION_OID );

        if ( responseValue != null )
        {
            this.responseValue = new byte[responseValue.length];
            System.arraycopy( responseValue, 0, this.responseValue, 0, responseValue.length );
        }
        else
        {
            this.responseValue = null;
        }

        decodeValue();
    }


    /**
     * Instantiates a new graceful disconnect.
     */
    public GracefulDisconnect()
    {
        super( 0, EXTENSION_OID );
        this.responseValue = null;
    }


    /**
     * Instantiates a new graceful disconnect.
     *
     * @param timeOffline the offline time after disconnect, in minutes
     * @param delay the delay before disconnect, in seconds
     */
    public GracefulDisconnect( int timeOffline, int delay )
    {
        super( 0, EXTENSION_OID );
        responseName = EXTENSION_OID;
        this.timeOffline = timeOffline;
        this.delay = delay;

        StringBuffer buf = new StringBuffer();
        buf.append( "The server will disconnect and will be unavailable for " ).append( timeOffline );
        buf.append( " minutes in " ).append( delay ).append( " seconds." );

        ldapResult.setErrorMessage( buf.toString() );
        ldapResult.setMatchedDn( null );
        ldapResult.setResultCode( ResultCodeEnum.UNAVAILABLE );

        encodeResponse();
    }


    private void decodeValue() throws DecoderException
    {
        GracefulDisconnectDecoder decoder = new GracefulDisconnectDecoder();
        org.apache.directory.shared.ldap.extras.extended.ads_impl.GracefulDisconnect codec = null;

        try
        {
            codec = (org.apache.directory.shared.ldap.extras.extended.ads_impl.GracefulDisconnect) decoder
                .decode( responseValue );
            this.timeOffline = codec.getTimeOffline();
            this.delay = codec.getDelay();
            ldapResult.setResultCode( ResultCodeEnum.SUCCESS );
            List<LdapURL> contexts = codec.getReplicatedContexts();

            for ( LdapURL ldapUrl : contexts )
            {
                replicatedContexts.addLdapUrl( ldapUrl.toString() );
            }
        }
        catch ( DecoderException e )
        {
            LOG.error( I18n.err( I18n.ERR_04169 ), e );
            throw e;
        }
    }


    private void encodeResponse()
    {
        org.apache.directory.shared.ldap.extras.extended.ads_impl.GracefulDisconnect codec = new org.apache.directory.shared.ldap.extras.extended.ads_impl.GracefulDisconnect();
        codec.setTimeOffline( this.timeOffline );
        codec.setDelay( this.delay );

        for ( String ldapUrlStr : replicatedContexts.getLdapUrls() )
        {
            LdapURL ldapUrl = null;

            try
            {
                ldapUrl = new LdapURL( ldapUrlStr );
            }
            catch ( LdapURLEncodingException e )
            {
                LOG.error( I18n.err( I18n.ERR_04170, ldapUrlStr ), e );
                continue;
            }

            codec.addReplicatedContexts( ldapUrl );
        }

        try
        {
            super.responseValue = codec.encode().array();
        }
        catch ( EncoderException e )
        {
            LOG.error( I18n.err( I18n.ERR_04171 ), e );
            throw new RuntimeException( e );
        }
    }


    // ------------------------------------------------------------------------
    // ExtendedResponse Interface Method Implementations
    // ------------------------------------------------------------------------

    /**
     * Gets the response OID specific encoded response values.
     * 
     * @return the response specific encoded response values.
     */
    public byte[] getResponseValue()
    {
        if ( responseValue == null )
        {
            encodeResponse();
        }

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


    /**
     * Sets the response OID specific encoded response values.
     * 
     * @param responseValue the response specific encoded response values.
     */
    public void setResponseValue( byte[] responseValue )
    {
        if ( responseValue == null )
        {
            this.responseValue = null;
            this.delay = 0;
            this.timeOffline = 0;
            this.replicatedContexts = new ReferralImpl();
            return;
        }
        
        ByteBuffer bb = ByteBuffer.wrap( responseValue );
        GracefulDisconnectContainer container = new GracefulDisconnectContainer();
        Asn1Decoder decoder = new Asn1Decoder();

        try
        {
            decoder.decode( bb, container );
        }
        catch ( DecoderException e )
        {
            LOG.error( I18n.err( I18n.ERR_04172 ), e );
        }

        org.apache.directory.shared.ldap.extras.extended.ads_impl.GracefulDisconnect codec = container
            .getGracefulDisconnect();
        this.delay = codec.getDelay();
        this.timeOffline = codec.getTimeOffline();

        for ( LdapURL ldapUrl : codec.getReplicatedContexts() )
        {
            replicatedContexts.addLdapUrl( ldapUrl.toString() );
        }

        this.responseValue = new byte[responseValue.length];
        System.arraycopy( responseValue, 0, this.responseValue, 0, responseValue.length );
    }


    /**
     * Gets the OID uniquely identifying this extended response (a.k.a. its
     * name).
     * 
     * @return the OID of the extended response type.
     */
    public String getResponseName()
    {
        return EXTENSION_OID;
    }


    /**
     * Sets the OID uniquely identifying this extended response (a.k.a. its
     * name).
     * 
     * @param oid the OID of the extended response type.
     */
    public void setResponseName( String oid )
    {
        throw new UnsupportedOperationException( I18n.err( I18n.ERR_04168, EXTENSION_OID ) );
    }


    // -----------------------------------------------------------------------
    // Parameters of the Extended Response Value
    // -----------------------------------------------------------------------

    /**
     * Gets the delay before disconnection, in seconds.
     *
     * @return the delay before disconnection
     */
    public int getDelay()
    {
        return delay;
    }


    /**
     * Sets the delay befor disconnection, in seconds.
     *
     * @param delay the new delay before disconnection
     */
    public void setDelay( int delay )
    {
        this.delay = delay;
    }


    /**
     * Gets the offline time after disconnection, in minutes.
     *
     * @return the offline time after disconnection
     */
    public int getTimeOffline()
    {
        return timeOffline;
    }


    /**
     * Sets the time offline after disconnection, in minutes.
     *
     * @param timeOffline the new time offline after disconnection
     */
    public void setTimeOffline( int timeOffline )
    {
        this.timeOffline = timeOffline;
    }


    /**
     * Gets the replicated contexts.
     *
     * @return the replicated contexts
     */
    public Referral getReplicatedContexts()
    {
        return replicatedContexts;
    }
}
