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

import javax.measure.Unit;
import javax.xml.bind.annotation.XmlTransient;
import org.opengis.parameter.ParameterValue;
import org.apache.sis.internal.util.Cloner;
import org.apache.sis.util.collection.WeakHashSet;
import org.apache.sis.util.resources.Errors;


/**
 * A parameter value which can not be modified. This implementation shall be used only with:
 *
 * <ul>
 *   <li>immutable {@linkplain #getDescriptor() descriptor},</li>
 *   <li>immutable or null {@linkplain #getUnit() unit}, and</li>
 *   <li>immutable or {@linkplain Cloneable cloneable} parameter {@linkplain #getValue() value}.</li>
 * </ul>
 *
 * If the parameter value implements the {@link Cloneable} interface and has a public {@code clone()} method,
 * then that value will be cloned every time the {@link #getValue()} method is invoked.
 * The value is not cloned by this method however; it is caller's responsibility to not modify the value of
 * the given {@code parameter} instance after this method call.
 *
 * <div class="section">Instances sharing</div>
 * If the {@link #create(ParameterValue)} method is invoked more than once with equal descriptor, value and unit,
 * then the method will return the same {@code UnmodifiableParameterValue} instance on a <cite>best effort</cite>
 * basis.
 *
 * <div class="note"><b>Rational:</b>
 * the same parameter value is often used in many different coordinate operations. For example all <cite>Universal
 * Transverse Mercator</cite> (UTM) projections use the same scale factor (0.9996) and false easting (500000 metres).
 * </div>
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.6
 *
 * @param <T>  the type of the value stored in this parameter.
 *
 * @since 0.6
 * @module
 */
@XmlTransient
final class UnmodifiableParameterValue<T> extends DefaultParameterValue<T> {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -4760030766220872555L;

    /**
     * Pool of parameter instances created in this running JVM.
     * See class javadoc for a rational about why we use a pool.
     */
    @SuppressWarnings("rawtypes")
    private static final WeakHashSet<UnmodifiableParameterValue> POOL =
            new WeakHashSet<>(UnmodifiableParameterValue.class);

    /**
     * Creates a new parameter with the same value than the given one.
     */
    private UnmodifiableParameterValue(final ParameterValue<T> value) {
        super(value);
    }

    /**
     * Returns an unmodifiable implementation of the given parameter value.
     * See class javadoc for more information.
     *
     * @param  <T>        the type of the value stored in the given parameter.
     * @param  parameter  the parameter to make unmodifiable, or {@code null}.
     * @return an unmodifiable implementation of the given parameter, or {@code null} if the given parameter was null.
     */
    static <T> UnmodifiableParameterValue<T> create(final ParameterValue<T> parameter) {
        if (parameter == null || parameter instanceof UnmodifiableParameterValue<?>) {
            return (UnmodifiableParameterValue<T>) parameter;
        } else {
            return POOL.unique(new UnmodifiableParameterValue<>(parameter));
        }
    }

    /**
     * If the value is cloneable, clones it before to return it.
     */
    @Override
    public T getValue() {
        T value = super.getValue();
        if (value instanceof Cloneable) try {
            value = getDescriptor().getValueClass().cast(Cloner.cloneIfPublic(value));
        } catch (CloneNotSupportedException e) {
            throw new UnsupportedOperationException(Errors.format(Errors.Keys.CloneNotSupported_1, value.getClass()), e);
        }
        return value;
    }

    /**
     * Do not allow modification of the parameter value.
     */
    @Override
    protected void setValue(final Object value, final Unit<?> unit) {
        throw new UnsupportedOperationException(Errors.format(Errors.Keys.UnmodifiableObject_1, getClass()));
    }

    /**
     * Returns a modifiable copy of this parameter.
     */
    @Override
    @SuppressWarnings("CloneDoesntCallSuperClone")
    public DefaultParameterValue<T> clone() {
        return new DefaultParameterValue<>(this);
    }
}
