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

import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.InvalidObjectException;
import java.io.IOException;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.iso.AbstractInternationalString;


/**
 * A copy of {@link org.apache.sis.util.iso.ResourceInternationalString} specialized for
 * {@link IndexedResourceBundle}. Compared to the public class, this specialization works
 * with integer resource keys and accepts arguments.
 *
 * <h2>Immutability and thread safety</h2>
 * This base class is immutable and thus inherently thread-safe.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 * @since   0.8
 * @module
 */
public abstract class ResourceInternationalString extends AbstractInternationalString implements Serializable {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -3910920973710535739L;

    /**
     * The key for the resource to fetch.
     */
    private transient short key;

    /**
     * {@code true} if the key has arguments. If {@code false}, then the {@link #arguments}
     * field shall be ignored. We can not rely on {@code null} arguments value because null
     * may be a valid value.
     */
    private final boolean hasArguments;

    /**
     * The argument(s), or {@code null} if none. Note that the user may also really want to
     * specify {@code null} as an argument value. We distinguish the two cases with the sign
     * of the {@link #key} value.
     */
    private final Object arguments;

    /**
     * Creates a new international string for the given key.
     *
     * @param key  the key for the resource to fetch.
     */
    protected ResourceInternationalString(final short key) {
        this.key     = key;
        hasArguments = false;
        arguments    = null;
    }

    /**
     * Creates a new international string for the given key and arguments.
     *
     * @param key        the key for the resource to fetch.
     * @param arguments  the argument(s).
     */
    protected ResourceInternationalString(final short key, final Object arguments) {
        this.key          = key;
        this.hasArguments = true;
        this.arguments    = arguments;
    }

    /**
     * Returns a handler for the constants declared in the inner {@code Keys} class.
     * This is used at serialization time in order to serialize the constant name
     * rather than its numeric value.
     *
     * @return a handler for the constants declared in the inner {@code Keys} class.
     */
    protected abstract KeyConstants getKeyConstants();

    /**
     * Returns the resource bundle for the given locale.
     *
     * @param  locale  the locale for which to get the resource bundle, or {@code null} for the default locale.
     * @return the resource bundle for the given locale.
     */
    protected abstract IndexedResourceBundle getBundle(final Locale locale);

    /**
     * Converts this international string to a log record.
     *
     * @param  level  the logging level.
     * @return a log record with the message of this international string.
     *
     * @since 1.0
     */
    public final LogRecord toLogRecord(final Level level) {
        final LogRecord record = new LogRecord(level, getKeyConstants().getKeyName(key));
        final IndexedResourceBundle resources = getBundle(null);
        record.setResourceBundleName(resources.getClass().getName());
        record.setResourceBundle(resources);
        if (hasArguments) {
            record.setParameters(resources.toArray(arguments));
        }
        return record;
    }

    /**
     * Returns a string in the specified locale.
     *
     * @param  locale  the desired locale for the string to be returned.
     * @return the string in the specified locale, or in a fallback locale.
     * @throws MissingResourceException if the key given to the constructor is invalid.
     */
    @Override
    public final String toString(final Locale locale) throws MissingResourceException {
        final IndexedResourceBundle resources = getBundle(locale);
        return hasArguments ? resources.getString(key, arguments) : resources.getString(key);
    }

    /**
     * Compares this international string with the specified object for equality.
     * Two {@code ResourceInternationalString} are considered equal if they are
     * of the same class and have been constructed with equal arguments.
     *
     * @param  object  the object to compare with this international string.
     * @return {@code true} if the given object is equal to this string.
     */
    @Override
    public final boolean equals(final Object object) {
        if (object == null || object.getClass() != getClass()) {
            return false;
        }
        final ResourceInternationalString that = (ResourceInternationalString) object;
        return (key == that.key) && (hasArguments == that.hasArguments) && Objects.deepEquals(arguments, that.arguments);
    }

    /**
     * Returns a hash code value for this international text.
     *
     * @return a hash code value for this international text.
     */
    @Override
    public final int hashCode() {
        return getClass().hashCode() ^ (key + 31*Utilities.deepHashCode(arguments)) ^ (int) serialVersionUID;
    }

    /**
     * Serializes this international string using the key name rather than numerical value.
     *
     * @param  out  the output stream where to serialize this object.
     * @throws IOException if an I/O error occurred while writing.
     */
    private void writeObject(final ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeUTF(getKeyConstants().getKeyName(key));
    }

    /**
     * Deserializes an object serialized by {@link #writeObject(ObjectOutputStream)}.
     *
     * @param  in  the input stream from which to deserialize an object.
     * @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();
        try {
            key = getKeyConstants().getKeyValue(in.readUTF());
        } catch (ReflectiveOperationException cause) {
            throw (InvalidObjectException) new InvalidObjectException(cause.toString()).initCause(cause);
        }
    }
}
