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

import java.io.*;
import java.util.*;

import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;

/**
 * <p>An <code>EISMappedRecord</code> acts as a <code>Record</code>
 * wrapper.  It allows database row field-value pair mappings to be used as a
 * mapped record implementation.
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class EISMappedRecord extends AbstractRecord {
    protected Map record;
    protected EISAccessor accessor;

    /**
     * Create a database row wrapper for the record.
     */
    public EISMappedRecord(Map record, EISAccessor accessor) {
        setRecord(record);
        setAccessor(accessor);
    }

    /**
     * INTERNAL:
     * getFields() is sued internally in a few places, so try to make that work for mapped records.
     */
    @Override
    public Vector<DatabaseField> getFields() {
        return new Vector<>(getRecord().keySet());
    }

    /**
     * INTERNAL:
     * getValues() is sued internally in a few places, so try to make that work for mapped records.
     */
    @Override
    public Vector getValues() {
        return new Vector(getRecord().values());
    }

    /**
     * Forward the request to the record.
     */
    @Override
    public Set keySet() {
        Set keys = getRecord().keySet();

        // Handle bug in Attunity record.  It returns null for the keys.
        if (keys == null) {
            return new HashSet(1);
        }
        return keys;
    }

    /**
     * Forward the request to the record.
     */
    @Override
    public Collection values() {
        return getRecord().values();
    }

    /**
     * Forward the request to the record.
     */
    @Override
    public int size() {
        return getRecord().size();
    }

    /**
     * Return if the row is empty.
     * For some reason Attunity MappedRecords think they are empty when not,
     * so always return false.
     */
    @Override
    public boolean isEmpty() {
        return false;
    }

    /**
     * Forward the request to the record.
     */
    @Override
    public void clear() {
        getRecord().clear();
    }

    /**
     * Forward the request to the record.
     */
    @Override
    public Object get(String key) {
        return getRecord().get(key);
    }

    /**
     * Forward the request to the record.
     * Wrapped nested records and collections to SDKFieldValues.
     */
    @Override
    public Object get(DatabaseField field) {
        Object value = get(field.getName());
        if (value instanceof Map) {
            Vector<EISMappedRecord> nestedRows = new Vector<>(1);
            nestedRows.add(new EISMappedRecord((Map)value, getAccessor()));
            value = nestedRows;
        } else if (value instanceof List) {
            List<?> values = (List<?>)value;
            Vector<Object> nestedValues = new Vector<>(values.size());
            for (int index = 0; index < values.size(); index++) {
                Object nestedValue = values.get(index);
                if (nestedValue instanceof Map) {
                    nestedValues.add(new EISMappedRecord((Map)values.get(index), getAccessor()));
                } else {
                    nestedValues.add(nestedValue);
                }
            }
            value = nestedValues;
        }
        return value;
    }

    /**
     * Check if the field is contained in the row.
     */
    @Override
    public boolean containsKey(String fieldName) {
        return get(fieldName) != null;
    }

    /**
     * Check if the field is contained in the row.
     */
    @Override
    public boolean containsKey(DatabaseField key) {
        return get(key) != null;
    }

    /**
     * Return the wrapped record.
     */
    public Map getRecord() {
        return record;
    }

    /**
     * Set the wrapped record.
     */
    public void setRecord(Map record) {
        this.record = record;
    }

    /**
     * Return the accessor.
     */
    public EISAccessor getAccessor() {
        return accessor;
    }

    /**
     * Set the accessor.
     */
    public void setAccessor(EISAccessor accessor) {
        this.accessor = accessor;
    }

    /**
     * Print all of the record keys and values.
     */
    @Override
    public String toString() {
        StringWriter writer = new StringWriter();
        writer.write(Helper.getShortClassName(getClass()));
        writer.write("(");

        for (Iterator<?> keysIterator = keySet().iterator(); keysIterator.hasNext();) {
            Object key = keysIterator.next();
            writer.write(Helper.cr());
            writer.write("\t");
            writer.write(String.valueOf(key));
            writer.write(" => ");
            writer.write(String.valueOf(get(key)));
        }
        writer.write(")");

        return writer.toString();
    }
}
