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


import javax.naming.InvalidNameException;

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


/**
 * Various hex and string manipulation methods that are more efficient then
 * chaining operations: all is done in the same buffer without creating a bunch
 * of intermediate String objects.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public final class Hex
{
    /** &lt;hex&gt; ::= [0x30-0x39] | [0x41-0x46] | [0x61-0x66] */
    private static final byte[] HEX_VALUE =
        {
            // 00 -> 0F
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            // 10 -> 1F
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            // 20 -> 2F
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            // 30 -> 3F ( 0, 1,2, 3, 4,5, 6, 7, 8, 9 )
             0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, 
             // 40 -> 4F ( A, B, C, D, E, F )
            -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
            // 50 -> 5F
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            // 60 -> 6F ( a, b, c, d, e, f )
            -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
            // 70 -> 7F
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    };

    /** Used to build output as Hex */
    private static final char[] HEX_CHAR =
        { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };


    private Hex()
    {
    }


    /**
     * Translate two chars to an hex value. The chars must be
     * in [a-fA-F0-9]
     *
     * @param high The high value
     * @param low The low value
     * @return A byte representation of the two chars
     */
    public static byte getHexValue( char high, char low )
    {
        if ( ( high > 127 ) || ( low > 127 ) )
        {
            return -1;
        }

        return ( byte ) ( ( HEX_VALUE[high] << 4 ) | HEX_VALUE[low] & 0xff );
    }


    /**
     * Translate two bytes to an hex value. The bytes must be
     * in [0-9a-fA-F]
     *
     * @param high The high value
     * @param low The low value
     * @return A byte representation of the two bytes
     */
    public static byte getHexValue( byte high, byte low )
    {
        if ( ( ( high & 0x7F ) != high ) || ( ( low & 0x7F ) != low ) )
        {
            return -1;
        }

        return ( byte ) ( ( HEX_VALUE[high] << 4 ) | HEX_VALUE[low] & 0xff );
    }


    /**
     * Return an hex value from a single char
     * The char must be in [0-9a-fA-F]
     *
     * @param c The char we want to convert
     * @return A byte between 0 and 15
     */
    public static byte getHexValue( char c )
    {
        if ( c > 127 )
        {
            return -1;
        }

        return HEX_VALUE[c];
    }


    /**
     * Decodes values of attributes in the DN encoded in hex into a UTF-8
     * String.  RFC2253 allows a DN's attribute to be encoded in hex.
     * The encoded value starts with a # then is followed by an even
     * number of hex characters.
     *
     * @param str the string to decode
     * @return the decoded string
     * @throws InvalidNameException If we can't decode the String to an UTF-8 String
     */
    public static String decodeHexString( String str ) throws InvalidNameException
    {
        if ( str == null || str.length() == 0 )
        {
            throw new InvalidNameException( I18n.err( I18n.ERR_17037_MUST_START_WITH_SHARP ) );
        }

        char[] chars = str.toCharArray();

        if ( chars[0] != '#' )
        {
            throw new InvalidNameException( I18n.err( I18n.ERR_17038_MUST_START_WITH_ESC_SHARP, str ) );
        }

        // the bytes representing the encoded string of hex
        // this should be ( length - 1 )/2 in size
        byte[] decoded = new byte[( chars.length - 1 ) >> 1];

        for ( int ii = 1, jj = 0; ii < chars.length; ii += 2, jj++ )
        {
            int ch = ( HEX_VALUE[chars[ii]] << 4 )
                + ( HEX_VALUE[chars[ii + 1]] & 0xff );
            decoded[jj] = ( byte ) ch;
        }

        return Strings.utf8ToString( decoded );
    }


    /**
     * Convert an escaoed list of bytes to a byte[]
     *
     * @param str the string containing hex escapes
     * @return the converted byte[]
     * @throws InvalidNameException If we can't convert the String to a byte[]
     */
    public static byte[] convertEscapedHex( String str ) throws InvalidNameException
    {
        if ( str == null )
        {
            throw new InvalidNameException( I18n.err( I18n.ERR_17039_NON_NULL_EXPECTED_STRING ) );
        }

        int length = str.length();

        if ( length == 0 )
        {
            throw new InvalidNameException( I18n.err( I18n.ERR_17040_EXPECTED_NON_EMPTY_STRING ) );
        }

        // create buffer and add everything before start of scan
        byte[] buf = new byte[str.length() / 3];
        int pos = 0;

        // start scaning until we find an escaped series of bytes
        for ( int i = 0; i < length; i++ )
        {
            char c = str.charAt( i );

            if ( c == '\\' )
            {
                // we have the start of a hex escape sequence
                if ( Chars.isHex( str, i + 1 ) && Chars.isHex( str, i + 2 ) )
                {
                    byte value = ( byte ) ( ( HEX_VALUE[str.charAt( i + 1 )] << 4 )
                        + ( HEX_VALUE[str.charAt( i + 2 )] & 0xff ) );

                    i += 2;
                    buf[pos++] = value;
                }
            }
            else
            {
                throw new InvalidNameException( I18n.err( I18n.ERR_17041_VALID_ESC_CHARS_EXPECTED ) );
            }
        }

        return buf;
    }


    /**
     * Converts an array of bytes into an array of characters representing the
     * hexadecimal values of each byte in order. The returned array will be
     * double the length of the passed array, as it takes two characters to
     * represent any given byte.
     *
     * @param data a byte[] to convert to Hex characters
     * @return A char[] containing hexadecimal characters
     */
    public static char[] encodeHex( byte[] data )
    {
        int l = data.length;

        char[] out = new char[l << 1];

        // two characters form the hex value.
        int j = 0;
        
        for ( int i = 0; i < l; i++ )
        {
            out[j++] = HEX_CHAR[( 0xF0 & data[i] ) >>> 4];
            out[j++] = HEX_CHAR[0x0F & data[i]];
        }

        return out;
    }
}
