/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.eis.cobol.helper;

import java.io.StringWriter;

import org.eclipse.persistence.internal.eis.cobol.ByteArrayException;
import org.eclipse.persistence.internal.eis.cobol.FieldMetaData;

/**
* <b>Purpose</b>: This class handles all the byte &lt;-&gt; string conversions. It handles
* ascii/binary/packed-decimal conversions.  This class is used by and dependent on <code>
* FieldMetaData</code>
*/
public class ByteConverter {

    /** This is the byte array that represents the byte data for the entire record */
    private byte[] myRecordData;

    /** This is the field that this particular <code>ByteConverter</code> is associatedd */
    FieldMetaData myFieldMetaData;

    /** This is the word size for the system, api is provided to change this if necessary */
    public static int wordSize = 2;

    /** This represents whether the system is little endian or not, api is provided to change
    * this if necessary. */
    private boolean isLittleEndian;

    /**
    * Default constructor
    */
    public ByteConverter() {
        initialize();
    }

    /**
    * constructor that accepts FieldMetaData and record data, this is the preferred constructor
    */
    public ByteConverter(FieldMetaData metaData, byte[] recordData) {
        initialize(metaData, recordData);
    }

    /**
    * no-argument initializer
    */
    protected void initialize() {
        isLittleEndian = false;
    }

    /**
    * accepts FieldMetaData and record data.
    */
    protected void initialize(FieldMetaData metaData, byte[] recordData) {
        myFieldMetaData = metaData;
        myRecordData = recordData;
        isLittleEndian = false;
    }

    /**
    * method returns littleEndian attribute
    */
    public boolean isLittleEndian() {
        return isLittleEndian;
    }

    /**
    * method sets littleEndian attribute
    */
    public void setIsLittleEndian(boolean newValue) {
        isLittleEndian = newValue;
    }

    /**
    * method returns wordSize attribute
    */
    public int getWordSize() {
        return wordSize;
    }

    /**
    * method sets wordSize attribute
    */
    public void setWordSize(int newWordSize) {
        wordSize = newWordSize;
    }

    /**
    * This method checks the field to see if it should have a decimal point added and inserts it
    * if needed.
    */
    protected String insertDecimalInString(String string) {
        if (getFieldMetaData().hasDecimal()) {
            int decimalPosition = this.getFieldMetaData().getDecimalPosition();
            if (decimalPosition < string.length()) {
                StringWriter writer = new StringWriter();
                writer.write(string.substring(0, decimalPosition - 1));
                writer.write(".");
                writer.write(string.substring(decimalPosition - 1));
                return writer.toString();
            }
        }
        return string;
    }

    /**
    * This method removes the decimal if needed
    */
    protected String removeDecimalInString(String string) {
        if (getFieldMetaData().hasDecimal()) {
            int decimalPosition = this.getFieldMetaData().getDecimalPosition();
            if (decimalPosition < string.length()) {
                StringWriter writer = new StringWriter();
                writer.write(string.substring(0, decimalPosition - 1));
                writer.write(string.substring(decimalPosition));
                return writer.toString();
            }
        }
        return string;
    }

    /**
    * This method is the primary public access for the byte converter to extract a string value
    * associated with a field, from a byte array associated with a record.
    */
    public String getStringValue() {
        int offset = this.getFieldMetaData().getOffset();
        String stringValue = null;
        if ((this.getFieldMetaData().getType() != FieldMetaData.BINARY) && (this.getFieldMetaData().getType() != FieldMetaData.MANTISSA) && (this.getFieldMetaData().getType() != FieldMetaData.PACKED_DECIMAL)) {
            int length = 0;
            while (length < this.getFieldMetaData().getSize()) {
                if (this.getRecordData()[offset + length] == 0) {
                    break;
                }
                length++;
            }
            stringValue = new String(this.getRecordData(), offset, length);
        } else if (this.getFieldMetaData().getType() == FieldMetaData.BINARY) {
            if (isLittleEndian()) {
                this.swapEndians(offset, this.getFieldMetaData().getSize());
            }
            stringValue = getStringFromBinaryData(offset, this.getFieldMetaData().getSize());
        } else if (this.getFieldMetaData().getType() == FieldMetaData.PACKED_DECIMAL) {
            stringValue = this.getStringValueFromPackedDecimal();
        } else {
            //todo: handle other types of data
            stringValue = null;
        }
        return insertDecimalInString(stringValue);
    }

    /**
    * This is the primary public access for writing string values associated with a field to a
    * byte array associated with a record.
    */
    public void setBytesToValue(String value) {
        value = removeDecimalInString(value);
        if ((this.getFieldMetaData().getType() != FieldMetaData.BINARY) && (this.getFieldMetaData().getType() != FieldMetaData.MANTISSA) && (this.getFieldMetaData().getType() != FieldMetaData.PACKED_DECIMAL)) {
            byte[] byteValue = value.getBytes();
            int length = byteValue.length;

            //assure length is within boundaries of the field
            if (length > this.getFieldMetaData().getSize()) {
                length = this.getFieldMetaData().getSize();
            }
            int i;
            int j;
            for (i = 0, j = this.getFieldMetaData().getOffset(); i < length; i++, j++) {
                this.getRecordData()[j] = byteValue[i];
            }

            //terminate the string
            if (length < this.getFieldMetaData().getSize()) {
                this.getRecordData()[j] = 0;
            }
        } else if (this.getFieldMetaData().getType() == FieldMetaData.BINARY) {
            this.setBinaryDataToStringValue(value, this.getFieldMetaData().getOffset(), this.getFieldMetaData().getSize());
        } else if (this.getFieldMetaData().getType() == FieldMetaData.PACKED_DECIMAL) {
            this.setByteArrayToPackedDecimalValue(value);
        } else {
            //todo: handle other types of data
        }
    }

    /**
    * getter for <code>FieldMetaData</code>
    */
    public FieldMetaData getFieldMetaData() {
        return myFieldMetaData;
    }

    /**
    * setter for <code>FieldMetaData</code>
    */
    public void setFieldMetaData(FieldMetaData newFieldMetaData) {
        myFieldMetaData = newFieldMetaData;
    }

    /**
    * getter for record data
    */
    public byte[] getRecordData() {
        return myRecordData;
    }

    /**
    * setter for record data
    */
    public void setRecordData(byte[] newRecordData) {
        myRecordData = newRecordData;
    }

    /**
    * this method builds a string value from a byte array containing packed-decimal data
    */
    protected String getStringValueFromPackedDecimal() {
        int mask = 0xf0;
        boolean signed = this.getFieldMetaData().isSigned();
        String sign = "";
        int offset = this.getFieldMetaData().getOffset();
        int size = this.getFieldMetaData().getSize();
        StringBuilder value = new StringBuilder();
        int position = 0;

        // Determine the sign if there is one
        if (signed) {
            byte signBits = (byte)(myRecordData[(offset + size) - 1] | mask);
            if (signBits == 0x0d) {
                sign = String.valueOf('-');
            } else if (signBits == 0x0c) {
                sign = String.valueOf('+');
            }
        }

        String stringValue;

        // Build hex string
        for (int i = offset; i < (offset + size); i++) {
            stringValue = Integer.toHexString(Helper.intFromByte(myRecordData[i]));
            // Added to handle strange behavior of toHexString method with negative numbers
            if (stringValue.length() > 2) {
                stringValue = stringValue.substring(stringValue.length() - 2);
            }
            value.append(stringValue);
        }

        // Count leading zeros
        while (value.charAt(position) == '0') {
            position++;
        }
        // Prepend sign and remove leading zeros
        if (signed) {
            value.replace(0, position, sign);
        } else {
            value.delete(0, position);
        }
        return value.toString();
    }

    /**
    * this method sets byte array data to a packed-decimal value held in the value argument
    */
    protected void setByteArrayToPackedDecimalValue(String value) {
        int size = this.getFieldMetaData().getSize();
        int offset = this.getFieldMetaData().getOffset();
        boolean signed = this.getFieldMetaData().isSigned();

        //determine the sign if there is one add it
        if (signed) {
            if (value.startsWith("-")) {
                value += "d";
            } else {
                value += "c";
            }
            value = value.substring(1);
        }
        //add F if unsigned
        else {
            value += "f";
        }

        //add leading zeros
        while (value.length() < (size * 2)) {
            value = "0" + value;
        }

        //write one byte at a time to array
        for (int i = offset, j = 0; i < (offset + size); i++, j += 2) {
            myRecordData[i] = Helper.byteFromInt(Helper.intFromHexString(value.substring(j, j + 2)));
        }
    }

    /**
    * this method will swap the ends of a byte in a byte array starting at <code>offset</code>
    * and ending at <code>end</code>
    */
    protected void swapEndians(int offset, int end) {
        if ((wordSize > 0) && ((wordSize % 2) == 0)) {
            int length = end - offset;
            int stop = end;

            //assure length is divisible by wordSize
            if ((length % wordSize) != 0) {
                int remainder = length % wordSize;
                stop = end - remainder;
            }
            int halfWord = wordSize / 2;
            byte highByte;
            byte lowByte;
            for (int i = offset; i < stop; i += wordSize) {
                for (int j = 0; j < halfWord; j++) {
                    highByte = myRecordData[i + j];
                    lowByte = myRecordData[i + j + halfWord];
                    myRecordData[i + j] = lowByte;
                    myRecordData[i + j + halfWord] = highByte;
                }
            }
        } else {
            throw ByteArrayException.unrecognizedDataType();
        }
    }

    /**
    * this method performs a bitwise twos complement on a section of a byte array starting at
    * <code>offset</code> and ending at <code>offset + length</code>
    */
    protected void twosComplement(int offset, int length) {
        int i;

        //perform a twos complement on the bytes in record data
        for (i = offset; i < (offset + length); i++) {
            myRecordData[i] = Helper.byteFromInt(~(Helper.intFromByte(myRecordData[i])));
        }
        i--;
        //add one to value
        while ((i >= offset) && (Helper.intFromByte(myRecordData[i]) == -1)) {
            myRecordData[i] += 1;
            i--;
        }
        if (i >= offset) {
            myRecordData[i] += 1;
        }
    }

    /**
    * This method builds a string value from a byte array section containing binary data
    */
    protected String getStringFromBinaryData(int offset, int size) {
        boolean signed = this.getFieldMetaData().isSigned();
        String sign = null;
        int total = 0;

        //check if it is signed and determine sign
        if (signed) {
            int mask = 0xff;
            byte highestByte = myRecordData[offset];
            if (((highestByte >> 3) & mask) == 0xff) {
                sign = "-";
                twosComplement(offset, size);
            } else {
                sign = "+";
            }
        }

        //loop through bytes accumulating total
        for (int i = (offset + size) - 1, j = 0; i >= offset; i--, j++) {
            if (Helper.intFromByte(myRecordData[i]) < 0) {
                myRecordData[i] &= 0x7f;
                total += Helper.power(2, ((j + 1) * 8) - 1);
            }
            total += (Helper.intFromByte(myRecordData[i]) * Helper.power(2, j * 8));
        }
        if (signed) {
            return sign + String.valueOf(total);
        } else {
            return String.valueOf(total);
        }
    }

    /**
    * this method sets a section of byte array to the value represented by the string <code> value
    * </code> using a binary representation.
    */
    protected void setBinaryDataToStringValue(String value, int offset, int size) {
        boolean isNegative = false;

        //remove +/-
        if (value.startsWith("-")) {
            isNegative = true;
            value = value.substring(1);
        } else if (value.startsWith("+")) {
            value = value.substring(1);
        }
        int total = Helper.integerFromString(value);

        //loop through total dividing down
        for (int i = offset, j = size - 1; i < (size + offset); i++, j--) {
            myRecordData[i] = Helper.byteFromInt(total / Helper.power(2, j * 8));
            total %= Helper.power(2, j * 8);
        }
        if (isNegative) {
            twosComplement(offset, size);
        }
    }
}
