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

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.KerberosMessageType;
import org.apache.directory.shared.kerberos.messages.KerberosMessage;
import org.apache.directory.shared.kerberos.messages.Ticket;


/**
 * The KDC-REP data structure. It will store the object described by the ASN.1 grammar :
 * <pre>
 * KDC-REP         ::= SEQUENCE {
 *         pvno            [0] INTEGER (5),
 *         msg-type        [1] INTEGER (11 -- AS -- | 13 -- TGS --),
 *         padata          [2] SEQUENCE OF PA-DATA OPTIONAL
 *                                 -- NOTE: not empty --,
 *         crealm          [3] Realm,
 *         cname           [4] &lt;PrincipalName&gt;,
 *         ticket          [5] &lt;Ticket@gt;,
 *         enc-part        [6] &lt;EncryptedData&gt;
 *                                 -- EncASRepPart or EncTGSRepPart,
 *                                 -- as appropriate
 * }
 * </pre>
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class KdcRep extends KerberosMessage
{
    /** The PA-DATAs */
    private List<PaData> paData;

    /** The client realm */
    private String crealm;

    /** A storage for a byte array representation of the realm */
    private byte[] crealmBytes;

    /** The client principal name */
    private PrincipalName cname;

    /** The ticket tickets */
    private Ticket ticket;

    /** Encoded part */
    private EncryptedData encPart;

    /** The decoded KDC-REP part */
    protected EncKdcRepPart encKdcRepPart;

    // Storage for computed lengths
    private int pvnoLength;
    private int msgTypeLength;
    private int paDataLength;
    private int paDataSeqLength;
    private int[] paDataLengths;
    private int cnameLength;
    private int crealmLength;
    private int ticketLength;
    private int encPartLength;
    private int kdcRepSeqLength;
    private int kdcRepLength;


    /**
     * Creates a new instance of KDC-REP.
     */
    public KdcRep( KerberosMessageType msgType )
    {
        super( msgType );
        paData = new ArrayList<>();
    }


    /**
     * @return the pvno
     */
    public int getPvno()
    {
        return getProtocolVersionNumber();
    }


    /**
     * @param pvno the pvno to set
     */
    public void setPvno( int pvno )
    {
        setProtocolVersionNumber( pvno );
    }


    /**
     * @return the paData
     */
    public List<PaData> getPaData()
    {
        return paData;
    }


    /**
     * @param paData the paData to set
     */
    public void addPaData( PaData paData )
    {
        this.paData.add( paData );
    }


    /**
     * Returns the client realm.
     *
     * @return The client realm.
     */
    public String getCRealm()
    {
        return crealm;
    }


    /**
     * Set the client realm
     * @param crealm the client realm
     */
    public void setCRealm( String crealm )
    {
        this.crealm = crealm;
    }


    /**
     * Returns the client {@link PrincipalName}.
     *
     * @return The client {@link PrincipalName}.
     */
    public PrincipalName getCName()
    {
        return cname;
    }


    /**
     * Set the client principalName
     * @param cname the client principalName
     */
    public void setCName( PrincipalName cname )
    {
        this.cname = cname;
    }


    /**
     * Returns the {@link Ticket}
     *
     * @return The {@link Ticket}
     */
    public Ticket getTicket()
    {
        return ticket;
    }


    /**
     * Set the Ticket
     * @param ticket the ticket to set
     */
    public void setTicket( Ticket ticket )
    {
        this.ticket = ticket;
    }


    /**
     * Returns the encrypted part as {@link EncryptedData}.
     *
     * @return The encrypted part as {@link EncryptedData}.
     */
    public EncryptedData getEncPart()
    {
        return encPart;
    }


    /**
     * @param encPart the encPart to set
     */
    public void setEncPart( EncryptedData encPart )
    {
        this.encPart = encPart;
    }


    /**
     * @return the encKdcRepPart
     */
    public EncKdcRepPart getEncKdcRepPart()
    {
        return encKdcRepPart;
    }


    /**
     * @param encKdcRepPart the encKdcRepPart to set
     */
    public void setEncKdcRepPart( EncKdcRepPart encKdcRepPart )
    {
        this.encKdcRepPart = encKdcRepPart;
    }


    /**
     * Compute the KDC-REP length
     * <pre>
     * KDC-REP :
     * 
     * 0x30 L1 KDC-REP sequence
     *  |
     *  +--&gt; 0xA0 0x03 pvno tag
     *  |     |
     *  |     +--&gt; 0x02 0x01 0x05 pvno (5)
     *  |
     *  +--&gt; 0xA1 0x03 msg-type tag
     *  |     |
     *  |     +--&gt; 0x02 0x01 0x0B/0x0D msg-type : either AS-REP (0x0B) or TGS-REP (0x0D)
     *  |     
     *  +--&gt; 0xA2 L2 pa-data tag
     *  |     |
     *  |     +--&gt; 0x30 L2-1 pa-data SEQ
     *  |           |
     *  |           +--&gt; 0x30 L2-1-1 pa-data
     *  |           |
     *  |           +--&gt; 0x30 L2-1-2 pa-data
     *  |           :
     *  |     
     *  +--&gt; 0xA3 L3 crealm tag
     *  |     |
     *  |     +--&gt; 0x1B L3-1 crealm
     *  |
     *  +--&gt; 0xA4 L4 cname tag
     *  |     |
     *  |     +--&gt; 0x30 L4-1 cname
     *  |
     *  +--&gt; 0xA5 L5 ticket tag
     *  |     |
     *  |     +--&gt; 0x61 L5-1 ticket
     *  |
     *  +--&gt; 0xA6 L6 enc-part tag
     *        |
     *        +--&gt; 0x30 L6-1 enc-part
     *  
     * </pre>       
     */
    public int computeLength()
    {
        // The pvno length
        pvnoLength = 1 + 1 + 1;
        kdcRepSeqLength = 1 + TLV.getNbBytes( pvnoLength ) + pvnoLength;

        // The msg-type length
        msgTypeLength = 1 + 1 + 1;
        kdcRepSeqLength += 1 + TLV.getNbBytes( msgTypeLength ) + msgTypeLength;

        // Compute the pa-data length.
        if ( !paData.isEmpty() )
        {
            paDataLengths = new int[paData.size()];
            int pos = 0;
            paDataSeqLength = 0;

            for ( PaData paDataElem : paData )
            {
                paDataLengths[pos] = paDataElem.computeLength();
                paDataSeqLength += paDataLengths[pos];
                pos++;
            }

            paDataLength = 1 + TLV.getNbBytes( paDataSeqLength ) + paDataSeqLength;
            kdcRepSeqLength += 1 + TLV.getNbBytes( paDataLength ) + paDataLength;
        }

        // The crealm length
        crealmBytes = Strings.getBytesUtf8( crealm );
        crealmLength = 1 + TLV.getNbBytes( crealmBytes.length ) + crealmBytes.length;
        kdcRepSeqLength += 1 + TLV.getNbBytes( crealmLength ) + crealmLength;

        // Compute the client principalName length
        cnameLength = cname.computeLength();
        kdcRepSeqLength += 1 + TLV.getNbBytes( cnameLength ) + cnameLength;

        // Compute the ticket length
        ticketLength = ticket.computeLength();
        kdcRepSeqLength += 1 + TLV.getNbBytes( ticketLength ) + ticketLength;

        // Compute the encrypted part
        encPartLength = encPart.computeLength();
        kdcRepSeqLength += 1 + TLV.getNbBytes( encPartLength ) + encPartLength;

        // compute the global size
        kdcRepLength = 1 + TLV.getNbBytes( kdcRepSeqLength ) + kdcRepSeqLength;

        return kdcRepLength;
    }


    /**
     * Encode the KDC-REP component
     * 
     * @param buffer The buffer containing the encoded result
     * @return The encoded component
     * @throws EncoderException If the encoding failed
     */
    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
    {
        if ( buffer == null )
        {
            throw new EncoderException( I18n.err( I18n.ERR_148 ) );
        }

        // The KDC-REP SEQ Tag
        buffer.put( UniversalTag.SEQUENCE.getValue() );
        buffer.put( TLV.getBytes( kdcRepSeqLength ) );

        // The PVNO -----------------------------------------------------------
        // The tag
        buffer.put( ( byte ) KerberosConstants.KDC_REP_PVNO_TAG );
        buffer.put( TLV.getBytes( pvnoLength ) );

        // The value
        BerValue.encode( buffer, getProtocolVersionNumber() );

        // The MSG-TYPE if any ------------------------------------------------
        // The tag
        buffer.put( ( byte ) KerberosConstants.KDC_REP_MSG_TYPE_TAG );
        buffer.put( TLV.getBytes( msgTypeLength ) );

        // The value
        BerValue.encode( buffer, getMessageType().getValue() );

        // The PD-DATA if any -------------------------------------------------
        if ( !paData.isEmpty() )
        {
            // The tag
            buffer.put( ( byte ) KerberosConstants.KDC_REP_PA_DATA_TAG );
            buffer.put( TLV.getBytes( paDataLength ) );

            // The sequence
            buffer.put( UniversalTag.SEQUENCE.getValue() );
            buffer.put( TLV.getBytes( paDataSeqLength ) );

            // The values
            for ( PaData paDataElem : paData )
            {
                paDataElem.encode( buffer );
            }
        }

        // The CREALM ---------------------------------------------------------
        // The tag
        buffer.put( ( byte ) KerberosConstants.KDC_REP_CREALM_TAG );
        buffer.put( TLV.getBytes( crealmLength ) );

        // The value
        buffer.put( UniversalTag.GENERAL_STRING.getValue() );
        buffer.put( TLV.getBytes( crealmBytes.length ) );
        buffer.put( crealmBytes );

        // The CNAME ----------------------------------------------------------
        // The tag
        buffer.put( ( byte ) KerberosConstants.KDC_REP_CNAME_TAG );
        buffer.put( TLV.getBytes( cnameLength ) );

        // The value
        cname.encode( buffer );

        // The TICKET ---------------------------------------------------------
        // The tag
        buffer.put( ( byte ) KerberosConstants.KDC_REP_TICKET_TAG );
        buffer.put( TLV.getBytes( ticketLength ) );

        // The value
        ticket.encode( buffer );

        // The ENC-PART -------------------------------------------------------
        // The tag
        buffer.put( ( byte ) KerberosConstants.KDC_REP_ENC_PART_TAG );
        buffer.put( TLV.getBytes( encPartLength ) );

        // The value
        encPart.encode( buffer );

        return buffer;
    }


    /**
     * Pretty print the instance
     */
    public String toString( String tabs )
    {
        StringBuilder sb = new StringBuilder();

        sb.append( tabs ).append(
            "\n>-------------------------------------------------------------------------------\n" );
        sb.append( tabs ).append( "KdcRep : " );

        if ( getMessageType() == KerberosMessageType.AS_REP )
        {
            sb.append( "AS-REP" ).append( '\n' );
        }
        else if ( getMessageType() == KerberosMessageType.TGS_REP )
        {
            sb.append( "TGS-REP" ).append( '\n' );
        }
        else
        {
            sb.append( "Unknown" ).append( '\n' );
        }

        sb.append( tabs ).append( "pvno : " ).append( getProtocolVersionNumber() ).append( '\n' );

        sb.append( tabs ).append( "msg-type : " ).append( getMessageType() ).append( '\n' );

        for ( PaData paDataElem : paData )
        {
            sb.append( tabs ).append( "padata : " ).append( paDataElem.toString( tabs + "    " ) ).append( '\n' );
        }

        sb.append( tabs ).append( "crealm : " ).append( crealm ).append( '\n' );
        sb.append( tabs ).append( "cname : " ).append( cname ).append( '\n' );
        sb.append( ticket.toString( tabs ) );
        sb.append( encPart.toString( tabs ) );
        sb.append( tabs ).append(
            "\n-------------------------------------------------------------------------------<\n" );

        return sb.toString();
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        return toString( "" );
    }
}
