/*
 *   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.kerberos.components;


import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import org.apache.directory.api.asn1.Asn1Object;
import org.apache.directory.api.asn1.EncoderException;
import org.apache.directory.api.asn1.ber.tlv.BerValue;
import org.apache.directory.api.asn1.ber.tlv.TLV;
import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
import org.apache.directory.api.util.Strings;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.shared.kerberos.KerberosConstants;
import org.apache.directory.shared.kerberos.KerberosTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * EncKrbCredPart  ::= [APPLICATION 29] SEQUENCE {
 *      ticket-info     [0] SEQUENCE OF KrbCredInfo,
 *      nonce           [1] UInt32 OPTIONAL,
 *      timestamp       [2] KerberosTime OPTIONAL,
 *      usec            [3] Microseconds OPTIONAL,
 *      s-address       [4] HostAddress OPTIONAL,
 *      r-address       [5] HostAddress OPTIONAL
 * }
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class EncKrbCredPart implements Asn1Object
{
    /** The logger */
    private static final Logger log = LoggerFactory.getLogger( EncKrbCredPart.class );

    /** Speedup for logs */
    private static final boolean IS_DEBUG = log.isDebugEnabled();

    /** list of KrbCredInfo */
    private List<KrbCredInfo> ticketInfo;

    /** the nonce */
    private Integer nonce;

    /** the timestamp */
    private KerberosTime timestamp;

    /** the microseconds part of the timestamp */
    private Integer usec;

    /** the sender's address */
    private HostAddress senderAddress;

    /** the recipient's address */
    private HostAddress recipientAddress;

    private int ticketInfoSeqLen;
    private int ticketInfoLen;
    private int nonceLen;
    private int timestampLen;
    private byte[] timestampBytes;
    private int usecLen;
    private int senderAddressLen;
    private int recipientAddressLen;
    private int encKrbCredPartSeqLen;
    private int encKrbCredPartLen;


    /**
     * computing length of EncKrbCredPart:
     * 
     * <pre>
     *  0x7D L1
     *   |
     *   +--> 0x30 L1-2 EncKrbCredPart seq tag
     *         |
     *         +--> 0xA0 L2 seq of KrbCredInfo tag
     *         |     |
     *         |     +--> 0x30 L2-2 seq tag
     *         |     |
     *         |     +--> 0x30 LL1 KrbCredInfo
     *         |     .      ....
     *         |     +--> 0x30 LLn KrbCredInfo
     *         |
     *         +--> 0xA1 L3 nonce tag
     *         |     |
     *         |     +--> 0x02 L3-2 nonce (UInt32)
     *         |
     *         +--> 0xA2 11 timestamp tag
     *         |     |
     *         |     +--> 0x18 0x0F timestamp (KerberosTime)
     *         |
     *         +--> 0xA3 L4 usec tag
     *         |     |
     *         |     +--> 0x02 L4-2 usec (Microseconds)
     *         |
     *         +--> 0xA4 L5 s-address tag
     *         |     |
     *         |     +--> 0x30 L5-2 s-address (HostAddress)
     *         |
     *         +--> 0xA5 L6 r-address tag
     *               |
     *               +--> 0x30 L6-2 s-address (HostAddress) 
     *   
     * </pre> 
     */
    @Override
    public int computeLength()
    {
        for ( KrbCredInfo kci : ticketInfo )
        {
            ticketInfoSeqLen += kci.computeLength();
        }

        ticketInfoLen = 1 + TLV.getNbBytes( ticketInfoSeqLen ) + ticketInfoSeqLen;

        encKrbCredPartSeqLen = 1 + TLV.getNbBytes( ticketInfoLen ) + ticketInfoLen;

        if ( nonce != null )
        {
            nonceLen = BerValue.getNbBytes( nonce );
            nonceLen = 1 + TLV.getNbBytes( nonceLen ) + nonceLen;
            encKrbCredPartSeqLen += 1 + TLV.getNbBytes( nonceLen ) + nonceLen;
        }

        if ( timestamp != null )
        {
            timestampBytes = timestamp.getBytes();
            timestampLen = 1 + TLV.getNbBytes( timestampBytes.length ) + timestampBytes.length;
            encKrbCredPartSeqLen += 1 + TLV.getNbBytes( timestampLen ) + timestampLen;
        }

        if ( usec != null )
        {
            usecLen = BerValue.getNbBytes( usec );
            usecLen = 1 + TLV.getNbBytes( usecLen ) + usecLen;
            encKrbCredPartSeqLen += 1 + TLV.getNbBytes( usecLen ) + usecLen;
        }

        if ( senderAddress != null )
        {
            senderAddressLen = senderAddress.computeLength();
            encKrbCredPartSeqLen += 1 + TLV.getNbBytes( senderAddressLen ) + senderAddressLen;
        }

        if ( recipientAddress != null )
        {
            recipientAddressLen = recipientAddress.computeLength();
            encKrbCredPartSeqLen += 1 + TLV.getNbBytes( recipientAddressLen ) + recipientAddressLen;
        }

        encKrbCredPartLen = 1 + TLV.getNbBytes( encKrbCredPartSeqLen ) + encKrbCredPartSeqLen;

        return 1 + TLV.getNbBytes( encKrbCredPartLen ) + encKrbCredPartLen;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
    {
        if ( buffer == null )
        {
            throw new EncoderException( I18n.err( I18n.ERR_148 ) );
        }

        try
        {
            //EncKrbCredPart application tag
            buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_TAG );
            buffer.put( TLV.getBytes( encKrbCredPartLen ) );

            //EncKrbCredPart sequence tag
            buffer.put( UniversalTag.SEQUENCE.getValue() );
            buffer.put( TLV.getBytes( encKrbCredPartSeqLen ) );

            // ticket-info tag
            buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_TICKET_INFO_TAG );
            buffer.put( TLV.getBytes( ticketInfoLen ) );

            // sequence of ticket-info seq tag
            buffer.put( UniversalTag.SEQUENCE.getValue() );
            buffer.put( TLV.getBytes( ticketInfoSeqLen ) );

            for ( KrbCredInfo ki : ticketInfo )
            {
                ki.encode( buffer );
            }

            if ( nonce != null )
            {
                // nonce tag and value
                buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_NONCE_TAG );
                buffer.put( TLV.getBytes( nonceLen ) );
                BerValue.encode( buffer, nonce );
            }

            if ( timestamp != null )
            {
                // timestamp tag and value
                buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_TIMESTAMP_TAG );
                buffer.put( TLV.getBytes( timestampLen ) );

                buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
                buffer.put( ( byte ) 0x0F );
                buffer.put( timestampBytes );
            }

            if ( usec != null )
            {
                // usec tag and value
                buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_USEC_TAG );
                buffer.put( TLV.getBytes( usecLen ) );
                BerValue.encode( buffer, usec );
            }

            if ( senderAddress != null )
            {
                // s-address tag and value
                buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_SENDER_ADDRESS_TAG );
                buffer.put( TLV.getBytes( senderAddressLen ) );
                senderAddress.encode( buffer );
            }

            if ( recipientAddress != null )
            {
                // r-address tag and value
                buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_RECIPIENT_ADDRESS_TAG );
                buffer.put( TLV.getBytes( recipientAddressLen ) );
                recipientAddress.encode( buffer );
            }
        }
        catch ( BufferOverflowException boe )
        {
            log.error( I18n.err( I18n.ERR_740_CANNOT_ENCODE_ENC_KRB_CRED_PART, 1 + TLV.getNbBytes( encKrbCredPartLen )
                + encKrbCredPartLen, buffer.capacity() ) );
            throw new EncoderException( I18n.err( I18n.ERR_138 ) );
        }

        if ( IS_DEBUG )
        {
            log.debug( "EncKrbCredPart encoding : {}", Strings.dumpBytes( buffer.array() ) );
            log.debug( "EncKrbCredPart initial value : {}", toString() );
        }

        return buffer;
    }


    /**
     * @return the ticketInfo
     */
    public List<KrbCredInfo> getTicketInfo()
    {
        return ticketInfo;
    }


    /**
     * @param ticketInfo the ticketInfo to set
     */
    public void setTicketInfo( List<KrbCredInfo> ticketInfo )
    {
        this.ticketInfo = ticketInfo;
    }


    /**
     * @return the nonce
     */
    public Integer getNonce()
    {
        return nonce;
    }


    /**
     * @param nonce the nonce to set
     */
    public void setNonce( Integer nonce )
    {
        this.nonce = nonce;
    }


    /**
     * @return the timestamp
     */
    public KerberosTime getTimestamp()
    {
        return timestamp;
    }


    /**
     * @param timestamp the timestamp to set
     */
    public void setTimestamp( KerberosTime timestamp )
    {
        this.timestamp = timestamp;
    }


    /**
     * @return the usec
     */
    public Integer getUsec()
    {
        return usec;
    }


    /**
     * @param usec the usec to set
     */
    public void setUsec( Integer usec )
    {
        this.usec = usec;
    }


    /**
     * @return the senderAddress
     */
    public HostAddress getSenderAddress()
    {
        return senderAddress;
    }


    /**
     * @param senderAddress the senderAddress to set
     */
    public void setSenderAddress( HostAddress senderAddress )
    {
        this.senderAddress = senderAddress;
    }


    /**
     * @return the recipientAddress
     */
    public HostAddress getRecipientAddress()
    {
        return recipientAddress;
    }


    /**
     * @param recipientAddress the recipientAddress to set
     */
    public void setRecipientAddress( HostAddress recipientAddress )
    {
        this.recipientAddress = recipientAddress;
    }


    /**
     * add KrbCredInfo object to the existing list of ticket-info
     *
     * @param info the KrbCredInfo
     */
    public void addTicketInfo( KrbCredInfo info )
    {
        if ( info == null )
        {
            throw new IllegalArgumentException();
        }

        if ( ticketInfo == null )
        {
            ticketInfo = new ArrayList<KrbCredInfo>();
        }

        ticketInfo.add( info );
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();

        sb.append( "EncKrbCredPart : {\n" );

        sb.append( "    ticketInfo: " ).append( ticketInfo ).append( '\n' );

        if ( nonce != null )
        {
            sb.append( "    nonce: " ).append( nonce ).append( '\n' );
        }

        if ( timestamp != null )
        {
            sb.append( "    timestamp: " ).append( timestamp ).append( '\n' );
        }

        if ( usec != null )
        {
            sb.append( "    usec: " ).append( usec ).append( '\n' );
        }

        if ( senderAddress != null )
        {
            sb.append( "    senderAddress: " ).append( senderAddress ).append( '\n' );
        }

        if ( recipientAddress != null )
        {
            sb.append( "    recipientAddress: " ).append( recipientAddress ).append( '\n' );
        }

        sb.append( "}\n" );

        return sb.toString();
    }
}
