/*
 * 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.apache.sis.util.iso;

import java.util.Map;
import java.util.Set;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Collections;
import java.util.Objects;
import java.io.Serializable;
import java.lang.reflect.Array;
import javax.xml.bind.annotation.XmlValue;
import org.opengis.util.MemberName;
import org.opengis.util.Record;
import org.opengis.util.RecordType;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.util.AbstractMapEntry;
import org.apache.sis.internal.metadata.RecordSchemaSIS;


/**
 * A list of logically related elements as (<var>name</var>, <var>value</var>) pairs in a dictionary.
 * By definition, all record members have a [1 … 1] multiplicity
 * (for a more flexible construct, see {@linkplain org.apache.sis.feature features}).
 * Since all members are expected to be assigned a value, the initial values on {@code DefaultRecord}
 * instantiation are unspecified. Some may be null, or some may be zero.
 *
 * <h2>Limitations</h2>
 * <ul>
 *   <li><b>Multi-threading:</b> {@code DefaultRecord} instances are <strong>not</strong> thread-safe.
 *       Synchronization, if needed, shall be done externally by the caller.</li>
 *   <li><b>Serialization:</b> this class is serializable if the associated {@code RecordType} and all
 *        values are also serializable. Note in particular that {@link DefaultRecordSchema} is currently
 *        <strong>not</strong> serializable, so users wanting serialization may need to define their own
 *        schema implementation.</li>
 * </ul>
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @author  Cullen Rombach (Image Matters)
 * @version 1.0
 *
 * @see DefaultRecordType
 * @see DefaultRecordSchema
 *
 * @since 0.5
 * @module
 */
public class DefaultRecord implements Record, Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -5293250754663538325L;

    /**
     * The type definition of this record. Can not be {@code null}.
     */
    final RecordDefinition definition;

    /**
     * The record values in an array. May be an array of primitive type for compactness,
     * which is why the type is not {@code Object[]}. Should never be {@code null}, except
     * temporarily during XML unmarshalling.
     */
    private Object values;

    /**
     * Creates a new record for the given record type.
     * The initial values are unspecified - they may be null or zero.
     * Callers can assign values by a call to {@link #setAll(Object[])}.
     *
     * @param type  the type definition of the new record.
     */
    public DefaultRecord(final RecordType type) {
        ArgumentChecks.ensureNonNull("type", type);
        if (type instanceof RecordDefinition) {
            definition = (RecordDefinition) type;
        } else {
            definition = new RecordDefinition.Adapter(type);
        }
        values = Array.newInstance(definition.baseValueClass(), definition.size());
    }

    /**
     * Creates a new record initialized to a shallow copy of the given record.
     * The members contained in the given record are <strong>not</strong> recursively copied.
     *
     * @param  record  the record to copy (can not be null).
     *
     * @since 0.8
     */
    @SuppressWarnings("SuspiciousSystemArraycopy")
    public DefaultRecord(final Record record) {
        this(record.getRecordType());
        if (record instanceof DefaultRecord) {
            final Object source = ((DefaultRecord) record).values;
            System.arraycopy(source, 0, values, 0, Array.getLength(source));
        } else {
            for (final Map.Entry<MemberName,Integer> entry : definition.memberIndices().entrySet()) {
                final MemberName name = entry.getKey();
                final Object value = record.locate(name);
                if (value != null) {
                    final int index = entry.getValue();
                    final Class<?> valueClass = definition.getValueClass(index);
                    if (valueClass != null && !valueClass.isInstance(value)) {
                        throw new ClassCastException(Errors.format(Errors.Keys.IllegalPropertyValueClass_3,
                                name, valueClass, value.getClass()));
                    }
                    Array.set(values, index, value);
                }
            }
        }
    }

    /**
     * Returns a SIS implementation with the name and members of the given arbitrary implementation.
     * This method performs the first applicable action in the following choices:
     *
     * <ul>
     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given object is already an instance of {@code DefaultRecord},
     *       then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code DefaultRecord} instance is created using the
     *       {@linkplain #DefaultRecord(Record) copy constructor} and returned.
     *       Note that this is a shallow copy operation, since the members contained
     *       in the given object are not recursively copied.</li>
     * </ul>
     *
     * @param  other The object to get as a SIS implementation, or {@code null} if none.
     * @return A SIS implementation containing the members of the given object
     *         (may be the given object itself), or {@code null} if the argument was {@code null}.
     *
     * @since 0.8
     */
    public static DefaultRecord castOrCopy(final Record other) {
        if (other == null || other instanceof DefaultRecord) {
            return (DefaultRecord) other;
        } else {
            return new DefaultRecord(other);
        }
    }

    /**
     * Returns the type definition of this record.
     *
     * @return the type definition of this record.
     */
    @Override
    public RecordType getRecordType() {
        return definition.getRecordType();
    }

    /**
     * Returns the dictionary of all (<var>name</var>, <var>value</var>) pairs in this record.
     * This method returns a view which will delegate all {@code get} and {@code put} operations to
     * the {@link #locate(MemberName)} and {@link #set(MemberName, Object)} methods respectively.
     *
     * @return the dictionary of all (<var>name</var>, <var>value</var>) pairs in this record.
     *
     * @see RecordType#getMemberTypes()
     */
    @Override
    public Map<MemberName, Object> getAttributes() {
        if (values == null) {                         // Should never be null, except temporarily at XML unmarshalling time.
            return Collections.emptyMap();
        }
        return new AbstractMap<MemberName, Object>() {
            /** Returns the number of members in the record. */
            @Override
            public int size() {
                return definition.size();
            }

            /** Delegates to {@code DefaultRecord.locate(name)}. */
            @Override
            public Object get(final Object name) {
                return (name instanceof MemberName) ? locate((MemberName) name) : null;
            }

            /** Delegates to {@code DefaultRecord.set(name, value)}. */
            @Override
            public Object put(final MemberName name, final Object value) {
                final Object previous = locate(name);
                set(name, value);
                return previous;
            }

            /** Returns a set containing all (<var>name</var>, <var>value</var>) pairs in the record. */
            @Override
            public Set<Map.Entry<MemberName, Object>> entrySet() {
                return new Entries();
            }
        };
    }

    /**
     * The set of map entries to be returned by {@code DefaultRecord.getAttributes().entrySet()}.
     * {@link AbstractMap} uses this set for providing a default implementation of most methods.
     */
    private final class Entries extends AbstractSet<Map.Entry<MemberName,Object>> {
        /** Returns the number of members in the record. */
        @Override
        public int size() {
            return definition.size();
        }

        /** Returns an iterator over all record members. */
        @Override
        public Iterator<Map.Entry<MemberName, Object>> iterator() {
            return new Iter();
        }
    }

    /**
     * The iterator to be returned by {@code DefaultRecord.getAttributes().entrySet().iterator()}.
     * {@link AbstractMap} (indirectly) and {@link AbstractSet} use this iterator for providing a
     * default implementation of most methods.
     */
    private final class Iter implements Iterator<Map.Entry<MemberName,Object>> {
        /** Index of the next record member to return in the iteration. */
        private int index;

        /** Returns {@code true} if there is more record members to iterate over. */
        @Override
        public boolean hasNext() {
            return index < definition.size();
        }

        /** Returns an entry containing the name and value of the next record member. */
        @Override
        public Map.Entry<MemberName, Object> next() {
            if (hasNext()) {
                return new Entry(index++);
            }
            throw new NoSuchElementException();
        }
    }

    /**
     * A single entry in the map returned by {@code DefaultRecord.getAttributes()}.
     * Operations on this entry delegate to {@link DefaultRecord#locate(MemberName)}
     * and {@link DefaultRecord#set(MemberName, Object)} methods.
     */
    private final class Entry extends AbstractMapEntry<MemberName,Object> {
        /** Index of the record member represented by this entry. */
        private final int index;

        /** Creates a new entry for the record member at the given index. */
        Entry(final int index) {
            this.index = index;
        }

        /** Returns the name of the record member contained in this entry. */
        @Override
        public MemberName getKey() {
            return definition.getName(index);
        }

        /** Returns the current record member value. */
        @Override
        public Object getValue() {
            return locate(getKey());
        }

        /** Sets the record member value and returns the previous value. */
        @Override
        public Object setValue(final Object value) {
            final MemberName name = getKey();
            final Object previous = locate(name);
            set(name, value);
            return previous;
        }
    }

    /**
     * Returns the value for an attribute of the specified name.
     *
     * @param  name  the name of the attribute to lookup.
     * @return the value of the attribute for the given name.
     */
    @Override
    public Object locate(final MemberName name) {
        final Integer index = definition.indexOf(name);
        return (index != null) ? Array.get(values, index) : null;
    }

    /**
     * Sets the value for the attribute of the specified name.
     *
     * @param  name   the name of the attribute to modify.
     * @param  value  the new value for the attribute.
     * @throws IllegalArgumentException if the given name is not a member of this record.
     * @throws ClassCastException if the given value is not an instance of the expected type for this record.
     */
    @Override
    public void set(final MemberName name, final Object value) {
        final Integer index = definition.indexOf(name);
        if (index == null) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.PropertyNotFound_2,
                    getRecordType().getTypeName(), name));
        }
        if (value != null) {
            final Class<?> valueClass = definition.getValueClass(index);
            if (valueClass != null && !valueClass.isInstance(value)) {
                throw new ClassCastException(Errors.format(Errors.Keys.IllegalPropertyValueClass_3,
                        name, valueClass, value.getClass()));
            }
        }
        Array.set(values, index, value);
    }

    /**
     * Sets all attribute values in this record, in attribute order.
     *
     * @param  newValues  the attribute values.
     * @throws IllegalArgumentException if the given number of values does not match the expected number.
     * @throws ClassCastException if a value is not an instance of the expected type for this record.
     */
    public void setAll(final Object... newValues) {
        ArgumentChecks.ensureNonNull("values", newValues);
        final int length = Array.getLength(values);
        if (newValues.length != length) {
            throw new IllegalArgumentException(Errors.format(
                    Errors.Keys.UnexpectedArrayLength_2, length, newValues.length));
        }
        for (int i=0; i<newValues.length; i++) {
            final Object value = newValues[i];
            if (value != null) {
                final Class<?> valueClass = definition.getValueClass(i);
                if (valueClass != null && !valueClass.isInstance(value)) {
                    throw new ClassCastException(Errors.format(Errors.Keys.IllegalPropertyValueClass_3,
                            definition.getName(i), valueClass, value.getClass()));
                }
            }
            Array.set(values, i, value);
        }
    }

    /**
     * Compares this record with the given object for equality.
     *
     * @param  object the object to compare with this record for equality.
     * @return {@code true} if both objects are equal.
     */
    @Override
    public boolean equals(final Object object) {
        if (object == this) {
            return true;                            // Slight optimization for a common case.
        }
        if (object != null && object.getClass() == getClass()) {
            final DefaultRecord that = (DefaultRecord) object;
            return definition.getRecordType().equals(that.definition.getRecordType()) &&
                   Objects.deepEquals(values, that.values);
        }
        return false;
    }

    /**
     * Returns a hash code value for this record.
     *
     * @return a hash code value for this record.
     */
    @Override
    public int hashCode() {
        return Utilities.deepHashCode(values) ^ definition.getRecordType().hashCode();
    }

    /**
     * Returns a string representation of this record.
     * The string representation is for debugging purpose and may change in any future SIS version.
     *
     * @return a string representation of this record.
     */
    @Override
    public String toString() {
        return definition.toString("Record", values);
    }




    //////////////////////////////////////////////////////////////////////////////////////////////////
    ////////                                                                                  ////////
    ////////                               XML support with JAXB                              ////////
    ////////                                                                                  ////////
    ////////        The following methods are invoked by JAXB using reflection (even if       ////////
    ////////        they are private) or are helpers for other methods invoked by JAXB.       ////////
    ////////        Those methods can be safely removed if Geographic Markup Language         ////////
    ////////        (GML) support is not needed.                                              ////////
    ////////                                                                                  ////////
    //////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Constructs an initially empty record expecting exactly one value as a string.
     * See {@link #setValue(String)} for a description of the supported XML content.
     */
    private DefaultRecord() {
        definition = RecordSchemaSIS.STRING;
    }

    /**
     * Returns the record value as a string.
     */
    @XmlValue
    private String getValue() {
        if (values != null) {
            switch (Array.getLength(values)) {
                case 0:  break;
                case 1:  return String.valueOf(Array.get(values, 0));
                default: return definition.toString(null, values);
            }
        }
        return null;
    }

    /**
     * Sets the record value as a string. This method is invoked at unmarshalling time.
     * A record can be anything, but usages that we have seen so far write a character
     * sequence or a code list. Examples:
     *
     * {@preformat xml
     *    <gco:Record>Alphanumeric values: Product is alphanumeric.</gco:Record>
     *    <gco:Record>Alphanumeric Text: Message contains alphanumeric text.</gco:Record>
     *    <gco:Record>Part A: Reflectivity presented as a tabular listing of alphanumerics.</gco:Record>
     *    <gco:Record>
     *      <gmd:CodeListValue codelist="someURL#DataQualityAssessment" codeListValue="intermediate">intermediate</gmd:CodeListValue>
     *    </gco:Record>
     * }
     *
     * @see <a href="https://issues.apache.org/jira/browse/SIS-419">SIS-419</a>
     */
    private void setValue(String value) {
        if (value != null && !(value = value.trim()).isEmpty()) {
            values = new String[] {value};
        }
    }
}
