/*
 * 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;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.persistence.internal.eis.cobol.helper.ByteConverter;
import org.eclipse.persistence.internal.eis.cobol.helper.Helper;
import org.eclipse.persistence.internal.helper.DatabaseField;

/**
* <b>Purpose</b>: This class defines the <code>FieldMetaData</code> interface it defines
* various behavior associated with a field and stores meta-information about the field.
* <code>ElementaryFieldMetaData</code> represents a field that contains a direct value and
* no subordinate fields, a root in the hierarchy.
*/
public class ElementaryFieldMetaData implements FieldMetaData {

    /** This is the record that contains this field */
    protected RecordMetaData myRecord;

    /** This is the name of the field */
    protected String myName;

    /** This is the size of the field */
    protected int mySize;

    /** This is the offset of the field within the record byte array */
    protected int myOffset;

    /** This is the type of data the field contains */
    protected int myType;

    /** This is true if this field is redefined */
    protected boolean isRedefine;

    /** This is the offset of the decimal position within the digits of a numeric field */
    protected int decimalPosition;

    /** This is the field that this field redefines */
    protected FieldMetaData myFieldRedefined;

    /** This is the number of elements in the array if this field is an array type */
    protected int myArraySize;

    /** This is populated if the arraySize is dependent on another field */
    protected String myDependentFieldName;

    /** This is true if the field is a numeric field that is signed */
    protected boolean isSigned;

    public ElementaryFieldMetaData() {
        initialize();
    }

    public ElementaryFieldMetaData(String fieldName, String recordName) {
        initialize(fieldName, recordName);
    }

    public ElementaryFieldMetaData(String fieldName, RecordMetaData record) {
        initialize(fieldName, record);
    }

    protected void initialize() {
        myRecord = new RecordMetaData();
        isRedefine = false;
        decimalPosition = -1;
        myArraySize = -1;
        isSigned = false;
        myDependentFieldName = "";
    }

    protected void initialize(String fieldName, String recordName) {
        myName = fieldName;
        myRecord = new RecordMetaData(recordName);
        isRedefine = false;
        decimalPosition = -1;
        myArraySize = -1;
        isSigned = false;
        myDependentFieldName = "";
    }

    protected void initialize(String fieldName, RecordMetaData record) {
        myName = fieldName;
        myRecord = record;
        isRedefine = false;
        decimalPosition = -1;
        myArraySize = -1;
        isSigned = false;
        myDependentFieldName = "";
    }

    /**
    * performs a deep copy of all the attributes of the field
    */
    @Override
    public FieldMetaData deepCopy() {
        FieldMetaData fieldCopy = new ElementaryFieldMetaData(myName, myRecord.getName());
        fieldCopy.setIsFieldRedefine(isRedefine);
        fieldCopy.setDecimalPosition(decimalPosition);
        fieldCopy.setArraySize(myArraySize);
        fieldCopy.setSize(mySize);
        fieldCopy.setOffset(myOffset);
        fieldCopy.setType(myType);
        if (isFieldRedefine()) {
            fieldCopy.setFieldRedefined(myFieldRedefined.deepCopy());
        }
        fieldCopy.setDependentFieldName(myDependentFieldName);
        fieldCopy.setIsSigned(isSigned);
        return fieldCopy;
    }

    /**
    * returns true if field is a signed numeric field
    */
    @Override
    public boolean isSigned() {
        return isSigned;
    }

    /**
    * setter for isSigned
    */
    @Override
    public void setIsSigned(boolean signed) {
        isSigned = signed;
    }

    /**
    * returns true if the field is a numeric field with a decimal marker
    */
    @Override
    public boolean hasDecimal() {
        if (decimalPosition == -1) {
            return false;
        } else {
            return true;
        }
    }

    /**
    * getter for decimalPosition
    */
    @Override
    public int getDecimalPosition() {
        return decimalPosition;
    }

    /**
    * setter for decimalPosition
    */
    @Override
    public void setDecimalPosition(int newPosition) {
        decimalPosition = newPosition;
    }

    /**
    * getter for myName
    */
    @Override
    public String getName() {
        return myName;
    }

    /**
    * setter for myName
    */
    @Override
    public void setName(String newName) {
        myName = newName;
    }

    /**
    * getter for myRecord
    */
    @Override
    public RecordMetaData getRecord() {
        return myRecord;
    }

    /**
    * setter for myRecord
    */
    @Override
    public void setRecord(RecordMetaData newRecord) {
        myRecord = newRecord;
    }

    /**
    * getter for mySize, multiplies field size my array size if field is an array to get
    * total size
    */
    @Override
    public int getSize() {

        /*if(this.isArray())
            return mySize * myArraySize;
        else*/
        return mySize;
    }

    /**
    * setter for mySize
    */
    @Override
    public void setSize(int size) {
        mySize = size;
    }

    /**
    * returns true if field is composite, since this is elementary, it always returns false
    */
    @Override
    public boolean isComposite() {
        return false;
    }

    /**
    * returns an empty vector since an elementary field should have no subordinate fields
    */
    public Vector getCompositeFields() {
        return new Vector();
    }

    /**
    * getter for myOffset
    */
    @Override
    public int getOffset() {
        return myOffset;
    }

    /**
    * setter for myOffset
    */
    @Override
    public void setOffset(int offset) {
        myOffset = offset;
    }

    /**
    * getter for myType
    */
    @Override
    public int getType() {
        return myType;
    }

    /**
    * setter for myType
    */
    @Override
    public void setType(int type) {
        myType = type;
    }

    /**
    * returns true if field is a redefine
    */
    @Override
    public boolean isFieldRedefine() {
        return isRedefine;
    }

    /**
    * setter for isRedefine
    */
    @Override
    public void setIsFieldRedefine(boolean status) {
        isRedefine = status;
    }

    /**
    * setter for myFieldRedefined
    */
    @Override
    public void setFieldRedefined(FieldMetaData field) {
        myFieldRedefined = field;
        if (field != null) {
            isRedefine = true;
        } else {
            isRedefine = false;
        }
    }

    /**
    * getter for myFieldRedefined
    */
    @Override
    public FieldMetaData getFieldRedefined() {
        return myFieldRedefined;
    }

    /**
    * returns true if field is an array
    */
    @Override
    public boolean isArray() {
        return (myArraySize > 0);
    }

    /**
    * getter for array size
    */
    @Override
    public int getArraySize() {
        return myArraySize;
    }

    /**
    * setter for myArraySize
    */
    @Override
    public void setArraySize(int newSize) {
        myArraySize = newSize;
    }

    /**
    * returns true if this field has a dependent field
    */
    @Override
    public boolean dependsOn() {
        return (!myDependentFieldName.isEmpty());
    }

    /**
    * getter for myDependentFieldName
    */
    @Override
    public String getDependentFieldName() {
        return myDependentFieldName;
    }

    /**
    * setter for myDependentFieldName
    */
    @Override
    public void setDependentFieldName(String fieldName) {
        myDependentFieldName = fieldName;
    }

    /**
    * this method extracts and returns the value for the field, if the field is an
    * array, the value is an <code>Vector</code>
    */
    @Override
    public Object extractValueFromArray(byte[] recordData) {
        Object value;
        if (this.isArray()) {
            int offset = this.getOffset();
            List<String> fieldValue = new ArrayList<>(this.getArraySize());
            for (int i = this.getArraySize(); i > 0; i--) {
                FieldMetaData fieldCopy = this.deepCopy();
                fieldCopy.setOffset(offset);
                ByteConverter converter = new ByteConverter(fieldCopy, recordData);
                fieldValue.add(converter.getStringValue());
                offset += mySize;
            }
            value = fieldValue;
        } else {
            ByteConverter converter = new ByteConverter(this, recordData);
            value = converter.getStringValue();
        }
        return value;
    }

    /**
    * this method adjusts the array size to the value in its dependent field
    */
    protected void adjustArraySize(CobolRow row) {
        Integer intValue = Helper.integerFromString(row.get(this.getDependentFieldName()).toString());
        if (intValue != null) {
            this.setArraySize(intValue);
        }
    }

    /**
    * this method will write its value to the row provided
    */
    @Override
    public void writeOnRow(CobolRow row, byte[] recordData) {
        DatabaseField field = new DatabaseField(this.getName(), this.getRecord().getName());
        Object value;

        //check for array first adjust size if necessary
        if (this.isArray() && this.dependsOn()) {
            adjustArraySize(row);
        }
        if (!this.isFieldRedefine()) {
            value = extractValueFromArray(recordData);
        }
        //redefined field handle accordingly
        else {
            value = new CobolRedefinedFieldValue(this, recordData);
        }
        row.add(field, value);

    }

    /**
    * this method will write its value from the row to the record data byte array
    */
    @Override
    public void writeOnArray(CobolRow row, byte[] recordData) {
        Object value = row.get(this.getName());
        ByteConverter converter;
        if (this.isArray()) {
            //check for array first adjust size if necessary
            if (this.dependsOn()) {
                adjustArraySize(row);
            }
            int offset = this.getOffset();
            @SuppressWarnings({"unchecked"})
            Iterator<String> elements = ((List<String>)value).iterator();
            for (int i = this.getArraySize(); i > 0; i--) {
                FieldMetaData fieldCopy = this.deepCopy();
                fieldCopy.setOffset(offset);
                converter = new ByteConverter(fieldCopy, recordData);
                String elementValue = elements.next();
                converter.setBytesToValue(elementValue);
                offset += mySize;
            }
        } else {
            converter = new ByteConverter(this, recordData);
            converter.setBytesToValue((String)value);
        }
    }
}
