/*
 * 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.LinkedHashMap;
import java.io.Serializable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.Array;
import javax.xml.bind.annotation.XmlTransient;
import org.opengis.util.Type;
import org.opengis.util.RecordType;
import org.opengis.util.MemberName;
import org.opengis.feature.AttributeType;
import org.apache.sis.util.Classes;
import org.apache.sis.util.Numbers;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.collection.Containers;
import org.apache.sis.internal.util.CollectionsExt;


/**
 * Holds a {@code Record} definition in a way more convenient for Apache SIS than
 * what the {@code RecordType} interface provides.
 *
 * <h2>Serialization</h2>
 * This base class is intentionally not serializable, and all private fields are marked as transient for making
 * this decision more visible. This is because the internal details of this class are quite arbitrary, so we do
 * not want to expose them in serialization for compatibility reasons. Furthermore some information are redundant,
 * so a serialization performed by subclasses may be more compact. Serialization of all necessary data shall be
 * performed by subclasses, and the transient fields shall be reconstructed by a call to
 * {@link #computeTransientFields(Map)}.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 * @since   0.5
 * @module
 */
@XmlTransient
abstract class RecordDefinition {                                       // Intentionally not Serializable.
    /**
     * {@code RecordDefinition} implementation used as a fallback when the user-supplied {@link RecordType}
     * is not an instance of {@link DefaultRecordType}. So this adapter is used only if Apache SIS is mixed
     * with other implementations.
     *
     * <h4>Serialization</h4>
     * This class is serializable if the {@code RecordType} given to the constructor is also serializable.
     */
    static final class Adapter extends RecordDefinition implements Serializable {
        /**
         * For cross-version compatibility.
         */
        private static final long serialVersionUID = 3739362257927222288L;

        /**
         * The wrapped record type.
         */
        private final RecordType recordType;            // This is the only serialized field in this file.

        /**
         * Creates a new adapter for the given record type.
         */
        Adapter(final RecordType recordType) {
            this.recordType = recordType;
            computeTransientFields(recordType.getMemberTypes());
        }

        /**
         * Invoked on deserialization for restoring the transient fields.
         *
         * @param  in  the input stream from which to deserialize an attribute.
         * @throws IOException if an I/O error occurred while reading or if the stream contains invalid data.
         * @throws ClassNotFoundException if the class serialized on the stream is not on the classpath.
         */
        private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
            in.defaultReadObject();
            computeTransientFields(recordType.getMemberTypes());
        }

        /**
         * Returns the wrapped record type.
         */
        @Override
        RecordType getRecordType() {
            return recordType;
        }
    }

    /**
     * Indices of member names. Created on construction or deserialization,
     * and shall be considered final and unmodifiable after that point.
     *
     * @see #memberIndices()
     */
    private transient Map<MemberName,Integer> memberIndices;

    /**
     * Member names. Created on construction or deserialization, and shall be considered
     * final and unmodifiable after that point.
     */
    private transient MemberName[] members;

    /**
     * Classes of expected values, or {@code null} if there is no restriction. Created on
     * construction or deserialization, and shall be considered final and unmodifiable after that point.
     */
    private transient Class<?>[] valueClasses;

    /**
     * The common parent of all value classes. May be a primitive type.
     */
    private transient Class<?> baseValueClass;

    /**
     * Creates a new instance. Subclasses shall invoke {@link #computeTransientFields(Map)} in their constructor.
     */
    RecordDefinition() {
    }

    /**
     * Returns the record type for which this object is a definition.
     */
    abstract RecordType getRecordType();

    /**
     * Invoked on construction or deserialization for computing the transient fields.
     *
     * @param  memberTypes  the (<var>name</var>, <var>type</var>) pairs in this record type.
     * @return the values in the given map. This information is not stored in {@code RecordDefinition}
     *         because not needed by this class, but the {@link DefaultRecordType} subclass will store it.
     */
    final Type[] computeTransientFields(final Map<? extends MemberName, ? extends Type> memberTypes) {
        final int size = memberTypes.size();
        members       = new MemberName[size];
        memberIndices = new LinkedHashMap<>(Containers.hashMapCapacity(size));
        final Type[] types = new Type[size];
        int i = 0;
        for (final Map.Entry<? extends MemberName, ? extends Type> entry : memberTypes.entrySet()) {
            final Type type = entry.getValue();
            if (type instanceof AttributeType) {
                final Class<?> c = ((AttributeType) type).getValueClass();
                if (c != Object.class) {
                    if (valueClasses == null) {
                        valueClasses = new Class<?>[size];
                    }
                    valueClasses[i] = c;
                    baseValueClass = Classes.findCommonClass(baseValueClass, c);
                }
            }
            final MemberName name = entry.getKey();
            members[i] = name;
            memberIndices.put(name, i);
            types[i] = type;
            i++;
        }
        memberIndices = CollectionsExt.unmodifiableOrCopy(memberIndices);
        baseValueClass = (baseValueClass != null) ? Numbers.wrapperToPrimitive(baseValueClass) : Object.class;
        return types;
    }

    /**
     * Returns the common parent of all value classes. May be a primitive type.
     */
    final Class<?> baseValueClass() {
        return baseValueClass;
    }

    /**
     * Read-only access to the map of member indices.
     */
    @SuppressWarnings("ReturnOfCollectionOrArrayField")
    final Map<MemberName,Integer> memberIndices() {
        return memberIndices;
    }

    /**
     * Returns the number of elements in records.
     */
    final int size() {
        // 'members' should not be null, but let be safe.
        return (members != null) ? members.length : 0;
    }

    /**
     * Returns the index of the given name, or {@code null} if none.
     */
    final Integer indexOf(final MemberName memberName) {
        return memberIndices.get(memberName);
    }

    /**
     * Returns the name of the member at the given index.
     */
    final MemberName getName(final int index) {
        return members[index];
    }

    /**
     * Returns the expected class of values in the given column, or {@code null} if unspecified.
     */
    final Class<?> getValueClass(final int index) {
        return (valueClasses != null) ? valueClasses[index] : null;
    }

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

    /**
     * Returns a string representation of a {@code Record} or {@code RecordType}.
     *
     * @param  head    either {@code "Record"} or {@code "RecordType"} or {@code null}.
     * @param  values  the values as an array, or {@code null} for writing the types instead.
     * @return the string representation.
     */
    final String toString(final String head, final Object values) {
        final StringBuilder buffer = new StringBuilder(250);
        final String lineSeparator = System.lineSeparator();
        final String[] names = new String[size()];
        final String margin;
        int width = 0;
        for (int i=0; i<names.length; i++) {
            width = Math.max(width, (names[i] = members[i].toString()).length());
        }
        if (head == null) {
            width  = 0;         // Ignore the width computation, but we still need the names in the array.
            margin = "";
        } else {
            buffer.append(head).append("[“").append(getRecordType().getTypeName()).append("”] {").append(lineSeparator);
            margin = "    ";
        }
        for (int i=0; i<names.length; i++) {
            final String name = names[i];
            buffer.append(margin).append(name);
            final Object value = (values != null) ? Array.get(values, i) : members[i].getAttributeType();
            if (value != null) {
                buffer.append(CharSequences.spaces(width - name.length())).append(" : ").append(value);
            }
            buffer.append(lineSeparator);
        }
        if (head != null) {
            buffer.append('}').append(lineSeparator);
        }
        return buffer.toString();
    }
}
