/*
 *  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.asn1.util;


import java.io.Serializable;

import org.apache.directory.shared.i18n.I18n;


/**
 * Implement the Bit String primitive type. A BitString is internally stored as
 * an array of byte.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class BitString implements Serializable
{
    /** The serialVersion UID constant */
    private static final long serialVersionUID = 1L;

    /** A null MutableString */
    public static final BitString EMPTY_STRING = new BitString( 1 );

    /** The number of unused bits in the last byte */
    private int nbUnusedBits;

    /** The string is stored in a byte array */
    private byte[] bytes;

    /** Actual length of the byte array */
    private int nbBytes;

    /** Actual length of the bit string */
    private int nbBits;


    /**
     * Creates a BitString with a specific length (length is the number of
     * bits).
     * 
     * @param length The BitString length (it's a number of bits)
     */
    public BitString( int length )
    {
        if ( length <= 0 )
        {
            // This is not allowed
            throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_00029_NULL_OR_NEG_LENGTH_NOT_ALLOWED ) );
        }

        nbBits = length;

        // As we store values in bytes, we must divide the length by 8
        nbBytes = ( length / 8 );

        if ( ( length % 8 ) != 0 )
        {
            nbBytes += 1;
        }

        nbUnusedBits = ( 8 - ( length % 8 ) ) & 0x07;

        bytes = new byte[nbBytes];
    }


    /**
     * Creates a BitString from a byte[]. As the first byteis the number of unused bits
     * in the last byte, we have to ignore it.
     * 
     * @param bytes The value to store. The first byte contains the number of
     * unused bits
     */
    public BitString( byte[] bytes )
    {
        if ( ( bytes == null ) || ( bytes.length == 0 ) )
        {
            nbBits = -1;
            return;
        }

        setData( bytes );
    }


    /**
     * Set a new BitString in the BitString. It will replace the old BitString,
     * and reset the current length with the new one.
     * 
     * @param bytes The string to store
     */
    public void setData( byte[] bytes )
    {
        if ( ( bytes == null ) || ( bytes.length == 0 ) )
        {
            nbBits = -1;
            return;
        }

        // The first byte contains the number of unused bits
        nbUnusedBits = bytes[0] & 0x07;
        nbBytes = bytes.length - 1;
        nbBits = ( nbBytes * 8 ) - nbUnusedBits;
        this.bytes = new byte[nbBytes];

        // We have to transfer the data
        for ( int i = 0; i < nbBytes; i++ )
        {
            this.bytes[i] = bytes[i + 1];
        }
    }


    /**
     * Get the representation of a BitString. A first byte containing the number
     * of unused bits is added
     * 
     * @return A byte array which represent the BitString
     */
    public byte[] getData()
    {
        byte[] copy = new byte[bytes.length + 1];

        System.arraycopy( bytes, 0, copy, 1, bytes.length );
        copy[0] = (byte)nbUnusedBits;

        return copy;
    }


    /**
     * Get the number of unused bits
     * 
     * @return A byte which represent the number of unused bits
     */
    public byte getUnusedBits()
    {
        return ( byte ) nbUnusedBits;
    }


    /**
     * Set a bit at a specified position. 
     * The bits are stored from left to right.
     * For instance, if we have 10 bits, then they are coded as b0 b1 b2 b3 b4 b5 b6 b7 - b8 b9 x x x x x x
     * 
     * @param pos The bit to set
     */
    public void setBit( int pos )
    {
        if ( ( pos < 0 ) || ( pos > nbBits ) )
        {
            throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_00030_BIT_NUMBER_OUT_OF_BOUND ) );
        }

        int posBytes = pos>>>3;
        int bitNumber = 7 - pos % 8;
        byte mask = (byte)( 1 << bitNumber );

        bytes[posBytes] |= mask;
    }


    /**
     * Clear a bit at a specified position. 
     * The bits are stored from left to right.
     * For instance, if we have 10 bits, then they are coded 
     * as b0 b1 b2 b3 b4 b5 b6 b7 - b8 b9 x x x x x x
     * 
     * @param pos The bit to clear
     */
    public void clearBit( int pos )
    {
        if ( ( pos < 0 ) || ( pos > nbBits ) )
        {
            throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_00030_BIT_NUMBER_OUT_OF_BOUND ) );
        }

        int posBytes = pos>>>3;
        int bitNumber = 7 - pos % 8;
        byte mask = (byte)( 1 << bitNumber );

        bytes[posBytes] &= ~mask;
    }


    /**
     * Get the bit stored into the BitString at a specific position. 
     * The bits are stored from left to right, the LSB on the left and the
     * MSB on the right
     * For instance, if we have 10 bits, then they are coded as 
     * b0 b1 b2 b3 - b4 b5 b6 b7 - b8 b9 x x - x x x x
     * 
     * With '1001 000x', where x is an unused bit, 
     *       ^ ^    ^ 
     *       | |    | 
     *       | |    |  
     *       | |    +----- getBit(6) = 0 
     *       | +---------- getBit(2) = 0 
     *       +------------ getBit(0) = 1
     *       
     * @param pos The position of the requested bit.  
     * 
     * @return <code>true</code> if the bit is set, <code>false</code>
     *         otherwise
     */
    public boolean getBit( int pos )
    {
        if ( pos > nbBits )
        {
            throw new IndexOutOfBoundsException( I18n.err( I18n.ERR_00031_CANNOT_FIND_BIT, pos, nbBits ) );
        }

        int posBytes = pos>>>3;
        int bitNumber = 7 - pos % 8;
        byte mask = (byte)( 1 << bitNumber );

        int res = bytes[posBytes] & mask;
        
        return res != 0;
    }


    /**
     * @return The number of bits stored in this BitString
     */
    public int size()
    {
        return nbBits;
    }


    /**
     * Return a native String representation of the BitString.
     * 
     * @return A String representing the BitString
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();

        for ( int i = 0; i < nbBits; i++ )
        {
            if ( getBit( i ) )
            {
                sb.append( '1' );
            }
            else
            {
                sb.append( '0' );
            }
        }

        return sb.toString();
    }
}
