/*******************************************************************************
 * 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.ofbiz.datafile;

import java.io.Serializable;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import org.ofbiz.base.crypto.HashCrypt;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.common.login.LoginServices;

/**
 * Record
 */
@SuppressWarnings("serial")
public class Record implements Serializable {

    /** Contains a map with field data by name */
    protected Map<String, Object> fields;

    /** Contains the name of the record definition */
    protected String recordName;

    /** Contains the definition for the record */
    protected transient ModelRecord modelRecord;

    protected Record parentRecord = null;
    protected List<Record> childRecords = new ArrayList<Record>();

    /** Creates new Record */
    protected Record(ModelRecord modelRecord) {
    if (modelRecord == null)
        throw new IllegalArgumentException("Cannont create a Record with a null modelRecord parameter");
    this.recordName = modelRecord.name;
    this.modelRecord = modelRecord;
    this.fields = new HashMap<String, Object>();
    }

    /** Creates new Record from existing Map */
    protected Record(ModelRecord modelRecord, Map<String, Object> fields) {
    if (modelRecord == null)
        throw new IllegalArgumentException("Cannont create a Record with a null modelRecord parameter");
    this.recordName = modelRecord.name;
    this.modelRecord = modelRecord;
    this.fields = (fields == null ? new HashMap<String, Object>() : new HashMap<String, Object>(fields));
    }

    public String getRecordName() {
    return recordName;
    }

    public ModelRecord getModelRecord() {
    if (modelRecord == null) {
        throw new IllegalStateException("[Record.getModelRecord] could not find modelRecord for recordName " + recordName);
    }
    return modelRecord;
    }

    public Object get(String name) {
    if (getModelRecord().getModelField(name) == null) {
        throw new IllegalArgumentException("[Record.get] \"" + name + "\" is not a field of " + recordName);
        // Debug.logWarning("[GenericRecord.get] \"" + name + "\" is not a field of " + recordName + ", but getting anyway...", module);
    }
    return fields.get(name);
    }

    public String getString(String name) {
    Object object = get(name);

    if (object == null)
        return null;
    if (object instanceof java.lang.String)
        return (String) object;
    else
        return object.toString();
    }

    public String getStringAndEmpty(String name) {
    Object object = get(name);

    if (object == null)
        return "";
    if (object instanceof java.lang.String)
        return (String) object;
    else
        return object.toString();
    }

    public java.sql.Timestamp getTimestamp(String name) {
    return (java.sql.Timestamp) get(name);
    }

    public java.sql.Time getTime(String name) {
    return (java.sql.Time) get(name);
    }

    public java.sql.Date getDate(String name) {
    return (java.sql.Date) get(name);
    }

    public Integer getInteger(String name) {
    return (Integer) get(name);
    }

    public Long getLong(String name) {
    return (Long) get(name);
    }

    public Float getFloat(String name) {
    return (Float) get(name);
    }

    public Double getDouble(String name) {
    return (Double) get(name);
    }

    /** Sets the named field to the passed value, even if the value is null
     * @param name The field name to set
     * @param value The value to set
     */
    public void set(String name, Object value) {
    set(name, value, true);
    }

    /** Sets the named field to the passed value. If value is null, it is only
     *  set if the setIfNull parameter is true.
     * @param name The field name to set
     * @param value The value to set
     * @param setIfNull Specifies whether or not to set the value if it is null
     */
    public synchronized void set(String name, Object value, boolean setIfNull) {
    if (getModelRecord().getModelField(name) == null) {
        throw new IllegalArgumentException("[Record.set] \"" + name + "\" is not a field of " + recordName);
        // Debug.logWarning("[GenericRecord.set] \"" + name + "\" is not a field of " + recordName + ", but setting anyway...", module);
    }
    if (value != null || setIfNull) {
        if (value instanceof Boolean) {
        value = ((Boolean) value).booleanValue() ? "Y" : "N";
        }
        fields.put(name, value);
    }
    }

    /**
     * little endian reader for 2 byte short.
     */
    public final short readLEShort(byte[] byteArray) {
    return  (short)(
        (byteArray[1]&0xff) << 8 |
        (byteArray[0]&0xff));

    }

    /**
     * little endian reader for 4 byte int.
     */
    public final int readLEInt(byte []byteArray) {
    return
    (byteArray[3])      << 24 |
    (byteArray[2]&0xff) << 16 |
    (byteArray[1]&0xff) <<  8 |
    (byteArray[0]&0xff);
    }

    /**
     * little endian reader for 8 byte long.
     */
    public final long readLELong(byte []byteArray) {
    return
    (long)(byteArray[7])      << 56 |  /* long cast needed or shift done modulo 32 */
    (long)(byteArray[6]&0xff) << 48 |
    (long)(byteArray[5]&0xff) << 40 |
    (long)(byteArray[4]&0xff) << 32 |
    (long)(byteArray[3]&0xff) << 24 |
    (long)(byteArray[2]&0xff) << 16 |
    (long)(byteArray[1]&0xff) <<  8 |
    (byteArray[0]&0xff);
    }

    /** Sets the named field to the passed value, converting the value from a String to the current type using <code>Type.valueOf()</code>
     * @param name The field name to set
     * @param value The String value to convert and set
     */
    public void setString(String name, String value) throws ParseException {
    if (name == null || value == null || value.equals(""))
        return;
    ModelField field = getModelRecord().getModelField(name);

    if (field == null)
        set(name, value); // this will get an error in the set() method...

    // if the string is all spaces ignore
    boolean nonSpace = false;

    for (int i = 0; i < value.length(); i++) {
        if (value.charAt(i) != ' ') {
        nonSpace = true;
        break;
        }
    }
    if (!nonSpace)
        return;

    // if (Debug.verboseOn()) Debug.logVerbose("Value: " + value, module);

    String fieldType = field.type;

    // first the custom types that need to be parsed
    if (fieldType.equals("CustomTimestamp")) {
        // this custom type will take a string a parse according to date formatting
        // string then put the result in a java.sql.Timestamp
        // a common timestamp format for flat files is with no separators: yyyyMMddHHmmss
        SimpleDateFormat sdf = new SimpleDateFormat(field.format);
        java.util.Date tempDate = sdf.parse(value);
        java.sql.Timestamp timestamp = new java.sql.Timestamp(tempDate.getTime());

        set(name, timestamp);
    } else if (fieldType.equals("CustomDate")) {
        // a common date only format for flat files is with no separators: yyyyMMdd or MMddyyyy
        SimpleDateFormat sdf = new SimpleDateFormat(field.format);
        java.util.Date tempDate = sdf.parse(value);
        java.sql.Date date = new java.sql.Date(tempDate.getTime());

        set(name, date);
    } else if (fieldType.equals("CustomTime")) {
        // a common time only format for flat files is with no separators: HHmmss
        SimpleDateFormat sdf = new SimpleDateFormat(field.format);
        java.util.Date tempDate = sdf.parse(value);
        java.sql.Time time = new java.sql.Time(tempDate.getTime());

        set(name, time);
    } else if (fieldType.equals("FixedPointDouble")) {
        // this custom type will parse a fixed point number according to the number
        // of decimal places in the formatting string then place it in a Double
        NumberFormat nf = NumberFormat.getNumberInstance();
        Number tempNum = nf.parse(value);
        double number = tempNum.doubleValue();
        double decimalPlaces = Double.parseDouble(field.format);
        double divisor = Math.pow(10.0, decimalPlaces);

        number = number / divisor;
        set(name, Double.valueOf(number));
    } // standard types
    else if (fieldType.equals("java.lang.String") || fieldType.equals("String"))
        if (field.format.equals("EncryptedString")) {
        String hashType = LoginServices.getHashType();
        set(name, HashCrypt.digestHash(hashType, value.getBytes()));
        } else {
        set(name, value);
        }
    else if (fieldType.equals("NullTerminatedString")) {
        int terminate = value.indexOf(0x0);
        set(name, terminate>0?value.substring(0,terminate):value);
    } else if (fieldType.equals("java.sql.Timestamp") || fieldType.equals("Timestamp"))
        set(name, java.sql.Timestamp.valueOf(value));
    else if (fieldType.equals("java.sql.Time") || fieldType.equals("Time"))
        set(name, java.sql.Time.valueOf(value));
    else if (fieldType.equals("java.sql.Date") || fieldType.equals("Date"))
        set(name, java.sql.Date.valueOf(value));
    else if (fieldType.equals("java.lang.Integer") || fieldType.equals("Integer"))
        set(name, Integer.valueOf(value));
    else if (fieldType.equals("java.lang.Long") || fieldType.equals("Long"))
        set(name, Long.valueOf(value));
    else if (fieldType.equals("java.lang.Float") || fieldType.equals("Float"))
        set(name, Float.valueOf(value));
    else if (fieldType.equals("java.lang.Double") || fieldType.equals("Double"))
        set(name, Double.valueOf(value));
    else if (fieldType.equals("LEShort"))
        set(name, Short.valueOf(readLEShort(value.getBytes())));
    else if (fieldType.equals("LEInteger"))
        set(name, Integer.valueOf(readLEInt(value.getBytes())));
    else if (fieldType.equals("LELong"))
        set(name, Long.valueOf(readLELong(value.getBytes())));
    else {
        throw new IllegalArgumentException("Field type " + fieldType + " not currently supported. Sorry.");
    }
    }

    public String getFixedString(String name) {
    if (name == null)
        return null;
    if (getModelRecord() == null)
        throw new IllegalArgumentException("Could not find modelrecord for field named \"" + name + "\"");
    ModelField field = getModelRecord().getModelField(name);

    if (field == null)
        throw new IllegalArgumentException("Could not find model for field named \"" + name + "\"");

    Object value = get(name);

    if (value == null) {
        return null;
    }

    String fieldType = field.type;
    String str = null;

    // first the custom types that need to be parsed
    if (fieldType.equals("CustomTimestamp")) {
        // a common timestamp format for flat files is with no separators: yyyyMMddHHmmss
        SimpleDateFormat sdf = new SimpleDateFormat(field.format);
        java.sql.Timestamp timestamp = (java.sql.Timestamp) value;

        str = sdf.format(new Date(timestamp.getTime()));
    } else if (fieldType.equals("CustomDate")) {
        // a common date only format for flat files is with no separators: yyyyMMdd or MMddyyyy
        SimpleDateFormat sdf = new SimpleDateFormat(field.format);
        java.sql.Date date = (java.sql.Date) value;

        str = sdf.format(new Date(date.getTime()));
    } else if (fieldType.equals("CustomTime")) {
        // a common time only format for flat files is with no separators: HHmmss
        SimpleDateFormat sdf = new SimpleDateFormat(field.format);
        java.sql.Time time = (java.sql.Time) value;

        str = sdf.format(new Date(time.getTime()));
    } else if (fieldType.equals("FixedPointDouble")) {
        // this custom type will parse a fixed point number according to the number
        // of decimal places in the formatting string then place it in a Double
        double decimalPlaces = Double.parseDouble(field.format);
        double multiplier = Math.pow(10.0, decimalPlaces);
        double dnum = multiplier * ((Double) value).doubleValue();
        long number = Math.round(dnum);

        str = padFrontZeros(Long.toString(number), field.length);
        // if (Debug.infoOn()) Debug.logInfo("[Record.getFixedString] FixedPointDouble: multiplier=" + multiplier + ", value=" + value + ", dnum=" + dnum + ", number=" + number + ", str=" + str, module);
    } // standard types
    else if (fieldType.equals("java.lang.String") || fieldType.equals("String"))
        str = value.toString();
    else if (fieldType.equals("java.sql.Timestamp") || fieldType.equals("Timestamp"))
        str = value.toString();
    else if (fieldType.equals("java.sql.Time") || fieldType.equals("Time"))
        str = value.toString();
    else if (fieldType.equals("java.sql.Date") || fieldType.equals("Date"))
        str = value.toString();
    // for all numbers, pad front with zeros if field length is specified
    else if (fieldType.equals("java.lang.Integer") || fieldType.equals("Integer"))
        str = padFrontZeros(value.toString(), field.length);
    else if (fieldType.equals("java.lang.Long") || fieldType.equals("Long"))
        str = padFrontZeros(value.toString(), field.length);
    else if (fieldType.equals("java.lang.Float") || fieldType.equals("Float"))
        str = padFrontZeros(value.toString(), field.length);
    else if (fieldType.equals("java.lang.Double") || fieldType.equals("Double"))
        str = padFrontZeros(value.toString(), field.length);
    else {
        throw new IllegalArgumentException("Field type " + fieldType + " not currently supported. Sorry.");
    }

    if (str != null && field.length > 0 && str.length() < field.length) {
        // pad the end with spaces
        StringBuilder strBuf = new StringBuilder(str);

        while (strBuf.length() < field.length)
        strBuf.append(' ');
        str = strBuf.toString();
    }
    return str;
    }

    public String writeLineString(ModelDataFile modelDataFile) throws DataFileException {
    ModelRecord modelRecord = getModelRecord();
    boolean isFixedRecord = ModelDataFile.SEP_FIXED_RECORD.equals(modelDataFile.separatorStyle);
    boolean isFixedLength = ModelDataFile.SEP_FIXED_LENGTH.equals(modelDataFile.separatorStyle);
    boolean isDelimited = ModelDataFile.SEP_DELIMITED.equals(modelDataFile.separatorStyle);

    StringBuilder lineBuf = new StringBuilder();

    for (ModelField modelField: modelRecord.fields) {
        String data = this.getFixedString(modelField.name);

        if (isDelimited && null != modelDataFile.textDelimiter) {
        lineBuf.append(modelDataFile.textDelimiter);
        }

        // if field is null (not set) then assume we want to pad the field
        char PAD_CHAR = ' ';

        if (data == null) {
        StringBuilder sb = new StringBuilder("");

        for (int i = 0; i < modelField.length; i++)
            sb.append(PAD_CHAR);
        data = sb.toString();
        }

        // Pad the record
        if (isFixedRecord) {
        while (modelField.position > lineBuf.length())
            lineBuf.append(" ");
        }
        // if (Debug.infoOn()) Debug.logInfo("Field: " + modelField.name + " Position: " + modelField.position + " BufLen: " + lineBuf.length(), module);

        // if (Debug.infoOn()) Debug.logInfo("Got data \"" + data + "\" for field " + modelField.name + " in record " + modelRecord.name, module);
        if (modelField.length > 0 && data.length() != modelField.length)
        throw new DataFileException("Got field length " + data.length() + " but expected field length is " + modelField.length + " for field \"" +
            modelField.name + "\" of record \"" + modelRecord.name + "\" data is: \"" + data + "\"");

        lineBuf.append(data);
        if (isDelimited) {
        if (null != modelDataFile.textDelimiter) {
            lineBuf.append(modelDataFile.textDelimiter);
        }
        lineBuf.append(modelDataFile.delimiter);
        }
    }

    if (isDelimited) {
        // just remove the last delimiter to finish clean, otherwise shows as extra column
        lineBuf.setLength(lineBuf.length() - 1);
    }

    if ((isFixedRecord || isFixedLength) && modelDataFile.recordLength > 0 && lineBuf.length() != modelDataFile.recordLength)
        throw new DataFileException("Got record length " + lineBuf.length() + " but expected record length is " + modelDataFile.recordLength +
            " for record \"" + modelRecord.name + "\" data line is: \"" + lineBuf + "\"");

    // for convenience, insert the type-code in where it is looked for, if exists
    if (modelRecord.tcPosition > 0 && modelRecord.typeCode.length() > 0) {
        lineBuf.replace(modelRecord.tcPosition, modelRecord.tcPosition + modelRecord.tcLength, modelRecord.typeCode);
    }

    if (isFixedLength || isDelimited)
        lineBuf.append('\n');

    return lineBuf.toString();
    }

    String padFrontZeros(String str, int totalLength) {
    if (totalLength > 0 && str.length() < totalLength) {
        // pad the front with zeros
        StringBuilder zeros = new StringBuilder();
        int numZeros = totalLength - str.length();

        for (int i = 0; i < numZeros; i++)
        zeros.append('0');
        zeros.append(str);
        return zeros.toString();
    } else
        return str;
    }

    public Record getParentRecord() {
    return parentRecord;
    }

    public List<Record> getChildRecords() {
    return childRecords;
    }

    public void addChildRecord(Record record) {
    childRecords.add(record);
    }

    /** Creates new Record
     * @param modelRecord
     * @throws DataFileException Exception thown for various errors, generally has a nested exception
     * @return return the Record Object created
     */
    public static Record createRecord(ModelRecord modelRecord) throws DataFileException {
    Record record = new Record(modelRecord);

    return record;
    }

    /** Creates new Record from existing fields Map
     * @param modelRecord
     * @param fields
     * @throws DataFileException Exception thown for various errors, generally has a nested exception
     * @return return the Record Object created
     */
    public static Record createRecord(ModelRecord modelRecord, Map<String, Object> fields) throws DataFileException {
    Record record = new Record(modelRecord, fields);

    return record;
    }

    /**
     * @param line
     * @param lineNum
     * @param modelRecord
     * @throws DataFileException Exception thown for various errors, generally has a nested exception
     * @return return the Record Object created
     */
    public static Record createRecord(String line, int lineNum, ModelRecord modelRecord) throws DataFileException {
    Record record = new Record(modelRecord);

    for (ModelField modelField: modelRecord.fields) {
        String strVal = null;


        try {
        strVal = line.substring(modelField.position, modelField.position + modelField.length);
        } catch (IndexOutOfBoundsException ioobe) {
        throw new DataFileException("Field " + modelField.name + " from " + modelField.position +
            " for " + modelField.length + " chars could not be read from a line (" + lineNum + ") with only " +
            line.length() + " chars.", ioobe);
        }
        try {
        record.setString(modelField.name, strVal);
        } catch (java.text.ParseException e) {
        throw new DataFileException("Could not parse field " + modelField.name + ", format string \"" + modelField.format + "\" with value " + strVal +
            " on line " + lineNum, e);
        } catch (java.lang.NumberFormatException e) {
        throw new DataFileException("Number not valid for field " + modelField.name + ", format string \"" + modelField.format + "\" with value " +
            strVal + " on line " + lineNum, e);
        }
    }
    return record;
    }

    /**
     * @param line
     * @param lineNum
     * @param modelRecord
     * @param delimiter
     * @throws DataFileException Exception thown for various errors, generally has a nested exception
     * @return return a Record Object
     */
    public static Record createDelimitedRecord(String line, int lineNum, ModelRecord modelRecord, char delimiter, String textDelimiter) throws DataFileException {
    Record record = new Record(modelRecord);

    StringTokenizer st = null;
    if (line.endsWith(String.valueOf(delimiter))) {
        st = new StringTokenizer(line + " ", "" + delimiter, true);
    }
    else {
        st = new StringTokenizer(line, "" + delimiter, true);
    }
    for (ModelField modelField: modelRecord.fields) {
        String strVal = null;

        if (modelField.expression) {
        if (UtilValidate.isNotEmpty(modelField.refField)) {
            strVal = record.getString(modelField.refField);
        }
        if (strVal == null) {
            strVal = (String)modelField.defaultValue;
        }
        } else {
        //some input lines may be less than the header model.
        if (st.hasMoreTokens()) {
            try {
            strVal = st.nextToken();
            if (strVal.equals("" + delimiter)) {
                strVal = null;
            } else if (st.hasMoreTokens()) {
                st.nextToken();
            }
            } catch (NoSuchElementException nsee) {
            throw new DataFileException("Field " + modelField.name + " could not be read from a line (" + lineNum + ") with only " +
                line.length() + " chars.", nsee);
            }                
        }
        else { //if input line is less than the header model then pad with null
            strVal = null;
        }
        }
        try {
        if (textDelimiter != null && (strVal.startsWith(textDelimiter) && strVal.endsWith(textDelimiter))) {
            strVal = strVal.substring(textDelimiter.length(), strVal.length() - textDelimiter.length());
        }
        record.setString(modelField.name, strVal);
        } catch (java.text.ParseException e) {
        throw new DataFileException("Could not parse field " + modelField.name + ", format string \"" + modelField.format + "\" with value " + strVal +
            " on line " + lineNum, e);
        } catch (java.lang.NumberFormatException e) {
        throw new DataFileException("Number not valid for field " + modelField.name + ", format string \"" + modelField.format + "\" with value " +
            strVal + " on line " + lineNum, e);
        }
    }
    return record;
    }

}

