/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.internal.sessions;

import java.io.StringWriter;
import java.util.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.internal.helper.DatabaseField;

/**
 * PERF: Optimized record implementation using arrays instead of Vector.
 * Currently only used when fetch rows from the database.
 */
public class ArrayRecord extends DatabaseRecord {
    protected DatabaseField[] fieldsArray;
    protected Object[] valuesArray;

    protected ArrayRecord() {
        super();
    }
    
    public ArrayRecord(Vector fields, DatabaseField[] fieldsArray, Object[] valuesArray) {
        super(fields, null, fieldsArray.length);
        this.fieldsArray = fieldsArray;
        this.valuesArray = valuesArray;
    }
    
    /**
     * Reset the fields and values from the arrays.
     * This removes the optimization if a non-optimized method is called.
     */
    protected void checkValues() {
        if (this.values == null) {
            this.values = new NonSynchronizedVector(this.valuesArray.length);
            for (Object value : this.valuesArray) {
                this.values.add(value);
            }
        }
    }

    /**
     * INTERNAL:
     * Add the field-value pair to the row.  Will not check,
     * will simply add to the end of the row
     */
    public void add(DatabaseField key, Object value) {
        checkValues();
        this.fieldsArray = null;
        this.valuesArray = null;
        super.add(key, value);
    }

    /**
     * PUBLIC:
     * Clear the contents of the row.
     */
    public void clear() {
        this.fieldsArray = null;
        this.valuesArray = null;
        super.clear();
    }

    /**
     * INTERNAL:
     * Clone the row and its values.
     */
    public AbstractRecord clone() {
        checkValues();
        return super.clone();
    }

    /**
     * INTERNAL:
     * Check if the field is contained in the row.
     */
    public boolean containsKey(DatabaseField key) {
        if (this.fieldsArray != null) {
            // Optimize check.
            int index = key.index;
            if ((index >= 0) && (index < this.size)) {
                DatabaseField field = this.fieldsArray[index];
                if ((field == key) || field.equals(key)) {
                    return true;
                }
            }
            for (DatabaseField field : this.fieldsArray) {
                if ((field == key) || field.equals(key)) {
                    return true;
                } 
            }
            return false;
        } else {
            return super.containsKey(key);
        }
    }

    /**
     * PUBLIC:
     * Check if the value is contained in the row.
     */
    public boolean containsValue(Object value) {
        if (this.valuesArray != null) {
            for (Object rowValue : this.valuesArray) {
                if ((value == rowValue) || rowValue.equals(value)) {
                    return true;
                } 
            }
            return false;
        } else {
            return super.containsValue(value);
        }
    }

    /**
     * INTERNAL:
     * Retrieve the value for the field. If missing null is returned.
     */
    public Object get(DatabaseField key) {
        if (this.fieldsArray != null) {
            // Optimize check.
            int index = key.index;
            if ((index >= 0) && (index < this.size)) {
                DatabaseField field = this.fieldsArray[index];
                if ((field == key) || field.equals(key)) {
                    return this.valuesArray[index];
                }
            }
            for (int fieldIndex = 0; fieldIndex < this.size; fieldIndex++) {
                DatabaseField field = this.fieldsArray[fieldIndex];
                if ((field == key) || field.equals(key)) {
                    // PERF: If the fields index was not set, then set it.
                    if (index == -1) {
                        key.setIndex(fieldIndex);
                    }
                    return this.valuesArray[fieldIndex];
                }
            }
            return null;
        } else {
            return super.get(key);
        }
    }
    
    /**
     * INTERNAL:
     * Retrieve the value for the field. If missing DatabaseRow.noEntry is returned.
     */
    public Object getIndicatingNoEntry(DatabaseField key) {
        if (this.fieldsArray != null) {
            // Optimize check.
            int index = key.index;
            if ((index >= 0) && (index < this.size)) {
                DatabaseField field = this.fieldsArray[index];
                if ((field == key) || field.equals(key)) {
                    return this.valuesArray[index];
                }
            }
            for (int fieldIndex = 0; fieldIndex < this.size; fieldIndex++) {
                DatabaseField field = this.fieldsArray[fieldIndex];
                if ((field == key) || field.equals(key)) {
                    // PERF: If the fields index was not set, then set it.
                    if (index == -1) {
                        key.setIndex(fieldIndex);
                    }
                    return this.valuesArray[fieldIndex];
                }
            }
            return AbstractRecord.noEntry;
        } else {
            return super.get(key);
        }
    }

    /**
     * INTERNAL:
     * Returns the row's field with the same name.
     */
    public DatabaseField getField(DatabaseField key) {
        if (this.fieldsArray != null) {
            // Optimize check.
            int index = key.index;
            if ((index >= 0) && (index < this.size)) {
                DatabaseField field = this.fieldsArray[index];
                if ((field == key) || field.equals(key)) {
                    return field;
                }
            }
            for (int fieldIndex = 0; fieldIndex < this.size; fieldIndex++) {
                DatabaseField field = this.fieldsArray[fieldIndex];
                if ((field == key) || field.equals(key)) {
                    return field;
                }
            }
            return null;
        } else {
            return super.getField(key);
        }
    }

    /**
     * INTERNAL:
     */
    public Vector getFields() {
        checkValues();
        return super.getFields();
    }

    /**
     * INTERNAL:
     */
    public Vector getValues() {
        checkValues();
        return super.getValues();
    }

    /**
     * INTERNAL:
     * Add the field-value pair to the row.
     */
    public Object put(DatabaseField key, Object value) {
        checkValues();
        this.fieldsArray = null;
        this.valuesArray = null;
        return super.put(key, value);
    }

    /**
     * INTERNAL:
     * Remove the field key from the row.
     */
    public Object remove(DatabaseField key) {
        checkValues();
        this.fieldsArray = null;
        this.valuesArray = null;
        return super.remove(key);
    }

    /**
     * INTERNAL:
     * replaces the value at index with value
     */
    public void replaceAt(Object value, int index) {
        if (this.valuesArray != null) {
            this.valuesArray[index] = value;
        } else {
            super.replaceAt(value, index);
        }
    }

    /**
     * INTERNAL:
     * replaces the value at field with value
     */
    public void replaceAt(Object value, DatabaseField key) {
        if (this.fieldsArray != null) {
            // Optimize check.
            int index = key.index;
            if ((index >= 0) && (index < this.size)) {
                DatabaseField field = this.fieldsArray[index];
                if ((field == key) || field.equals(key)) {
                    this.valuesArray[index] = value;
                    return;
                }
            }
            for (int fieldIndex = 0; fieldIndex < this.size; fieldIndex++) {
                DatabaseField field = this.fieldsArray[fieldIndex];
                if ((field == key) || field.equals(key)) {
                    // PERF: If the fields index was not set, then set it.
                    if (index == -1) {
                        key.setIndex(fieldIndex);
                    }
                    this.valuesArray[fieldIndex] = value;
                    return;
                }
            }
        } else {
            super.replaceAt(value, key);
        }
    }

    protected void setFields(Vector fields) {
        checkValues();
        this.fieldsArray = null;
        this.valuesArray = null;
        super.setFields(fields);
    }
    
    protected void setValues(Vector values) {
        checkValues();
        this.fieldsArray = null;
        this.valuesArray = null;
        super.setValues(values);
    }

    /**
     * PUBLIC:
     * Return the number of field/value pairs in the row.
     */
    public int size() {
        if (this.fieldsArray == null) {
            return this.fields.size();
        } else {
            return this.fieldsArray.length;            
        }
    }

    @Override
    public String toString() {
        if (this.valuesArray != null) {
            StringWriter writer = new StringWriter();
            writer.write(Helper.getShortClassName(getClass()));
            writer.write("(");
            writer.write(toStringAditional());
            for (int index = 0; index < this.fieldsArray.length; index++) {
                writer.write(Helper.cr());
                writer.write("\t");
                writer.write(String.valueOf(this.fieldsArray[index]));
                writer.write(" => ");
                writer.write(String.valueOf(this.valuesArray[index]));
            }
            if (this.sopObject != null) {
                writer.write(Helper.cr());
                writer.write(" sopObject = ");
                writer.write(this.sopObject.toString());
            }
            writer.write(")");
    
            return writer.toString();
        } else {
            return super.toString();
        }
    }
    
    protected String toStringAditional() {
        return "";
    }
}
