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

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * dump data in hexadecimal format
 */
@Internal
public final class HexDump {
    public static final String EOL = System.getProperty("line.separator");
    public static final Charset UTF8 = StandardCharsets.UTF_8;

    private HexDump() {
        // all static methods, so no need for a public constructor
    }

    /**
     * dump an array of bytes to an OutputStream
     *
     * @param data the byte array to be dumped
     * @param offset its offset, whatever that might mean
     * @param stream the OutputStream to which the data is to be
     *               written
     * @param index initial index into the byte array
     * @param length number of characters to output
     *
     * @exception IOException is thrown if anything goes wrong writing
     *            the data to stream
     * @exception ArrayIndexOutOfBoundsException if the index is
     *            outside the data array's bounds
     * @exception IllegalArgumentException if the output stream is
     *            null
     */
    public static void dump(final byte [] data, final long offset,
        final OutputStream stream, final int index, final int length)
    throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException {
        if (stream == null) {
            throw new IllegalArgumentException("cannot write to nullstream");
        }

        OutputStreamWriter osw = new OutputStreamWriter(stream, UTF8);
        osw.write(dump(data, offset, index, length));
        osw.flush();
    }

    /**
     * dump an array of bytes to an OutputStream
     *
     * @param data the byte array to be dumped
     * @param offset its offset, whatever that might mean
     * @param stream the OutputStream to which the data is to be
     *               written
     * @param index initial index into the byte array
     *
     * @exception IOException is thrown if anything goes wrong writing
     *            the data to stream
     * @exception ArrayIndexOutOfBoundsException if the index is
     *            outside the data array's bounds
     * @exception IllegalArgumentException if the output stream is
     *            null
     */

    public synchronized static void dump(final byte [] data, final long offset,
            final OutputStream stream, final int index)
    throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException {
        dump(data, offset, stream, index, Integer.MAX_VALUE);
    }

    /**
     * dump an array of bytes to a String
     *
     * @param data the byte array to be dumped
     * @param offset its offset, whatever that might mean
     * @param index initial index into the byte array
     *
     * @exception ArrayIndexOutOfBoundsException if the index is
     *            outside the data array's bounds
     * @return output string
     */

    public static String dump(final byte [] data, final long offset, final int index) {
        return dump(data, offset, index, Integer.MAX_VALUE);
    }

    /**
     * dump an array of bytes to a String
     *
     * @param data the byte array to be dumped
     * @param offset its offset, whatever that might mean
     * @param index initial index into the byte array
     * @param length number of characters to output
     *
     * @exception ArrayIndexOutOfBoundsException if the index is
     *            outside the data array's bounds
     * @return output string
     */

    public static String dump(final byte [] data, final long offset, final int index, final int length) {
        if (data == null || data.length == 0) {
            return "No Data"+EOL;
        }

        int data_length = (length == Integer.MAX_VALUE || length < 0 || index+length < 0)
            ? data.length
            : Math.min(data.length,index+length);


        if ((index < 0) || (index >= data.length)) {
            String err = "illegal index: "+index+" into array of length "+data.length;
            throw new ArrayIndexOutOfBoundsException(err);
        }

        long  display_offset = offset + index;
        StringBuilder buffer = new StringBuilder(74);

        for (int j = index; j < data_length; j += 16) {
            int chars_read = data_length - j;

            if (chars_read > 16) {
                chars_read = 16;
            }

            writeHex(buffer, display_offset, 8, "");
            for (int k = 0; k < 16; k++) {
                if (k < chars_read) {
                    writeHex(buffer, data[ k + j ], 2, " ");
                } else {
                    buffer.append("   ");
                }
            }
            buffer.append(' ');
            for (int k = 0; k < chars_read; k++) {
                buffer.append(toAscii(data[ k + j ]));
            }
            buffer.append(EOL);
            display_offset += chars_read;
        }
        return buffer.toString();
    }

    public static char toAscii(int dataB) {
        char charB = (char)(dataB & 0xFF);
        if (Character.isISOControl(charB)) {
            return '.';
        }

        switch (charB) {
            // printable, but not compilable with current compiler encoding
            case 0xFF:
            case 0xDD:
                charB = '.';
                break;
            default:
                break;
        }
        return charB;
    }

    /**
     * Converts the parameter to a hex value.
     *
     * @param value     The value to convert
     * @return          A String representing the array of bytes
     */
    public static String toHex(final byte[] value)
    {
        StringBuilder retVal = new StringBuilder();
        retVal.append('[');
        if (value != null && value.length > 0)
        {
            for(int x = 0; x < value.length; x++)
            {
                if (x>0) {
                    retVal.append(", ");
                }
                retVal.append(toHex(value[x]));
            }
        }
        retVal.append(']');
        return retVal.toString();
    }

    /**
     * Converts the parameter to a hex value.
     *
     * @param value     The value to convert
     * @return          The result right padded with 0
     */
    public static String toHex(short value) {
        StringBuilder sb = new StringBuilder(4);
        writeHex(sb, value & 0xFFFF, 4, "");
        return sb.toString();
    }

    /**
     * Converts the parameter to a hex value.
     *
     * @param value     The value to convert
     * @return          The result right padded with 0
     */
    public static String toHex(byte value) {
        StringBuilder sb = new StringBuilder(2);
        writeHex(sb, value & 0xFF, 2, "");
        return sb.toString();
    }

    /**
     * Converts the parameter to a hex value.
     *
     * @param value     The value to convert
     * @return          The result right padded with 0
     */
    public static String toHex(int value) {
        StringBuilder sb = new StringBuilder(8);
        writeHex(sb, value & 0xFFFFFFFFL, 8, "");
        return sb.toString();
    }

    /**
     * Converts the parameter to a hex value.
     *
     * @param value     The value to convert
     * @return          The result right padded with 0
     */
    public static String toHex(long value) {
        StringBuilder sb = new StringBuilder(16);
        writeHex(sb, value, 16, "");
        return sb.toString();
    }

    /**
     * @return string of 16 (zero padded) uppercase hex chars and prefixed with '0x'
     */
    public static String longToHex(long value) {
        StringBuilder sb = new StringBuilder(18);
        writeHex(sb, value, 16, "0x");
        return sb.toString();
    }

    /**
     * @return string of 8 (zero padded) uppercase hex chars and prefixed with '0x'
     */
    public static String intToHex(int value) {
        StringBuilder sb = new StringBuilder(10);
        writeHex(sb, value & 0xFFFFFFFFL, 8, "0x");
        return sb.toString();
    }

    /**
     * @return string of 4 (zero padded) uppercase hex chars and prefixed with '0x'
     */
    public static String shortToHex(int value) {
        StringBuilder sb = new StringBuilder(6);
        writeHex(sb, value & 0xFFFFL, 4, "0x");
        return sb.toString();
    }

    /**
     * @return string of 2 (zero padded) uppercase hex chars and prefixed with '0x'
     */
    public static String byteToHex(int value) {
        StringBuilder sb = new StringBuilder(4);
        writeHex(sb, value & 0xFFL, 2, "0x");
        return sb.toString();
    }

    /**
     * @see Integer#toHexString(int)
     * @see Long#toHexString(long)
     */
    private static void writeHex(StringBuilder sb, long value, int nDigits, String prefix) {
        sb.append(prefix);
        char[] buf = new char[nDigits];
        long acc = value;
        for(int i=nDigits-1; i>=0; i--) {
            int digit = Math.toIntExact(acc & 0x0F);
            buf[i] = (char) (digit < 10 ? ('0' + digit) : ('A' + digit - 10));
            acc >>>= 4;
        }
        sb.append(buf);
    }
}
