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

import java.util.Arrays;
import java.util.Set;
import java.util.EnumSet;
import java.util.Iterator;
import org.apache.sis.math.FunctionProperty;
import org.apache.sis.util.Classes;
import org.apache.sis.util.ObjectConverter;
import org.apache.sis.util.UnconvertibleObjectException;
import org.apache.sis.util.collection.TreeTable;
import org.apache.sis.util.ArgumentChecks;


/**
 * Fallback to be used when the first converter failed.
 * In case of failure, the error of the first (primary) converter is reported.
 *
 * <p>The primary converter is expected more generic than the fallback converter. We try the generic
 * converter first because we expect that if the user wanted the specific subclass, he would have
 * asked explicitly for it. Trying the generic converter first is both closer to what the user
 * asked and less likely to throw many exceptions before we found a successful conversion.</p>
 *
 * <p>All converters in a {@code FallbackConverter} tree have the same source class {@code <S>},
 * and different target classes {@code <? extends T>} <strong>not</strong> equal to {@code <T>}.
 * The tree should never have two classes {@code <T1>} and {@code <T2>} such as one is assignable
 * from the other.</p>
 *
 * <p>Instances are created by the {@link #merge(ObjectConverter, ObjectConverter)} method.
 * It is invoked when a new converter is {@linkplain ConverterRegistry#register(ObjectConverter)
 * registered} for the same source and target class than an existing converter.</p>
 *
 * <h2>Immutability and thread safety</h2>
 * This class is immutable, and thus inherently thread-safe,
 * if the converters given to the static factory method are also immutable.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.3
 *
 * @param <S>  the base type of source objects.
 * @param <T>  the base type of converted objects.
 *
 * @since 0.3
 * @module
 */
final class FallbackConverter<S,T> extends SystemConverter<S,T> {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = 6331789192804695560L;

    /**
     * The primary converter, to be tried first.
     */
    final ObjectConverter<S, ? extends T> primary;

    /**
     * The fallback converter. Its target type should not be assignable from the primary target
     * type, except if both converters have the same target type. We intend {@linkplain #primary}
     * to be the most generic converter, because we assume that if the user wanted a more specific
     * type he would have asked explicitly for it. In addition this layout reduces the amount of
     * exceptions to be thrown and caught before we found a successful conversion.
     */
    final ObjectConverter<S, ? extends T> fallback;

    /**
     * Creates a converter using the given primary and fallback converters. This method may
     * interchange the two converters in order to met the {@linkplain #fallback} contract.
     *
     * @param  sourceClass  the {@linkplain #getSourceClass() source class}.
     * @param  targetClass  the {@linkplain #getTargetClass() target class}.
     * @param  primary      a first converter.
     * @param  fallback     a second converter.
     *
     * @see #merge(ObjectConverter, ObjectConverter)
     */
    private FallbackConverter(final Class<S> sourceClass, final Class<T> targetClass,
                              final ObjectConverter<S, ? extends T> primary,
                              final ObjectConverter<S, ? extends T> fallback)
    {
        super(sourceClass, targetClass);
        if (needSwap(primary, fallback.getClass())) {
            this.primary  = fallback;
            this.fallback = primary;
        } else {
            this.primary  = primary;
            this.fallback = fallback;
        }
    }

    /**
     * Returns {@code true} if the given primary and fallback converters should be interchanged.
     * This method may invoke itself recursively.
     *
     * @param  primary        the primary converter to test.
     * @param  fallbackClass  the target class of the fallback converter to test.
     * @return {@code true} if the given primary and fallback converters should be interchanged.
     */
    private static <S> boolean needSwap(final ObjectConverter<S,?> primary, final Class<?> fallbackClass) {
        if (primary instanceof FallbackConverter<?,?>) {
            final FallbackConverter<S,?> candidate = (FallbackConverter<S,?>) primary;
            return needSwap(candidate.primary,  fallbackClass) &&
                   needSwap(candidate.fallback, fallbackClass);
        } else {
            final Class<?> targetClass = primary.getTargetClass();
            return fallbackClass.isAssignableFrom(targetClass) && // This condition is more likely to fail first.
                    !targetClass.isAssignableFrom(fallbackClass);
        }
    }

    /**
     * Appends the given {@code converter} in the given tree of fallback converters.
     * This method may create a new {@code FallbackConverter} if the given converter
     * can not be inserted in the given tree.
     *
     * <p>This method has no information about {@code <T>} type because of parameterized types
     * erasure, and should not need that information if we didn't made a mistake in this class.
     * Nevertheless for safety, callers are encouraged to verify themselves as below:</p>
     *
     * {@preformat java
     *     Class<T> targetClass = ...;
     *     FallbackConverter<S, ? extends T> converter = merge(...);
     *     assert targetClass.isAssignableFrom(converter.getTargetClass()) : converter;
     * }
     *
     * In the current implementation, the {@code primary} converter can be either an arbitrary
     * {@code ObjectConverter}, or a previously created {@code FallbackConverter}. However the
     * {@code fallback} converter shall <strong>not</strong> be a {@code FallbackConverter}.
     * This restriction exists because the tree built in such case would probably not be the
     * desired one. It should be okay if only SIS code deal with {@code FallbackConverter}.
     *
     * @param  <S>       the base type of source objects.
     * @param  <T>       the base type of converted objects.
     * @param  primary   the first converter, which may be a {@code Fallback} tree.
     * @param  fallback  a new fallback to insert in the converters tree.
     * @return a tree of converters which contains the given {@code converter}. May be either
     *         {@code existing}, {@code converter} or a new {@code FallbackConverter} instance.
     */
    public static <S,T> ObjectConverter<S, ? extends T> merge(
                  final ObjectConverter<S, ? extends T> primary,
                  final ObjectConverter<S, ? extends T> fallback)
    {
        ArgumentChecks.ensureNonNull("primary",  primary);
        ArgumentChecks.ensureNonNull("fallback", fallback);
        assert !(fallback instanceof FallbackConverter<?,?>) : fallback; // See javadoc
        final ObjectConverter<S, ? extends T> candidate = mergeIfSubtype(primary, fallback, null);
        if (candidate != null) {
            return candidate;
        }
        final Class<S>           source  = primary .getSourceClass();
        final Class<? extends T> target1 = primary .getTargetClass();
        final Class<? extends T> target2 = fallback.getTargetClass();
        Class<?> target = Classes.findCommonClass(target1, target2);
        if (target == Object.class) {
            /*
             * If there is no common parent class other than Object, looks for a common interface.
             * We perform this special processing for Object.class because this class is handled
             * in a special way by the Java language anyway: all interfaces are specialization of
             * Object (in the sense "are assignable to"), so Object can be considered as a common
             * root for both classes and interfaces.
             */
            final Set<Class<?>> interfaces = Classes.findCommonInterfaces(target1, target2);
            interfaces.removeAll(Arrays.asList(Classes.getAllInterfaces(source)));
            final Iterator<Class<?>> it = interfaces.iterator();
            if (it.hasNext()) {
                /*
                 * Arbitrarily retains the first interface. At this point there is hopefully
                 * only one occurrence anyway. If there is more than one interface, they appear
                 * in declaration order so the first one is assumed the "main" interface.
                 */
                target = it.next();
            }
        }
        /*
         * We perform an unchecked cast because in theory <T> is the common super class.
         * However we can not check at run time because generic types are implemented by
         * erasure. If there is no logical error in our algorithm, the cast should be ok.
         * Nevertheless callers are encouraged to verify as documented in the Javadoc.
         */
        assert target.isAssignableFrom(target1) : target1;
        assert target.isAssignableFrom(target2) : target2;
        @SuppressWarnings({"unchecked","rawtypes"})
        final FallbackConverter<S, ? extends T> converter =
                new FallbackConverter(source, target, primary, fallback);
        return converter;
    }

    /**
     * Merges if the {@code converter} target class of is a subtype of the {@code branch}
     * target class. Otherwise returns {@code null}.
     *
     * <p>The {@code branch} can be either an arbitrary {@code ObjectConverter}, or a previously
     * created {@code FallbackConverter}. However the {@code converter} shall be a new instance,
     * <strong>not</strong> a {@code FallbackConverter} instance.
     * See {@link #merge(ObjectConverter, ObjectConverter)} javadoc for more information.</p>
     *
     * @param  <S>           the source class of the {@code branch} converter.
     * @param  <T>           the target class of the {@code branch} converter
     * @param  branch        the converter to eventually merge with {@code converter}.
     * @param  converter     the converter to eventually merge with {@code branch}.
     * @param  parentTarget  to be given verbatim to {@link #merge(ObjectConverter, Class)}.
     * @return the merged converter, or {@code null} if the {@code converter}
     *         target class is not a subtype of the {@code branch} target class.
     */
    private static <S,T> ObjectConverter<S, ? extends T> mergeIfSubtype(
            final ObjectConverter<S,T> branch,
            final ObjectConverter<S,?> converter,
            final Class<? super T> parentTarget)
    {
        if (branch.equals(converter)) {
            return branch;
        }
        final Class<T> targetClass = branch.getTargetClass();
        if (!targetClass.isAssignableFrom(converter.getTargetClass())) {
            return null;
        }
        /*
         * At this point we know that 'converter.targetClass' is <T> or a subtype of <T>,
         * so the cast below is safe. If the branch is an instance of FallbackConverter,
         * continue to follow that branch.
         */
        @SuppressWarnings("unchecked")
        final ObjectConverter<S, ? extends T> checked = (ObjectConverter<S, ? extends T>) converter;
        if (branch instanceof FallbackConverter<?,?>) {
            /*
             * Will follow either 'branch.fallback' or 'branch.primary', depending which one
             * is the most appropriate. If none can be followed, then the result will be the
             * same than in the 'else' block.
             */
            return ((FallbackConverter<S,T>) branch).merge(checked, parentTarget);
        } else {
            /*
             * Both 'branch' and 'checked' are ordinary converters (not FallbackConverter).
             */
            return new FallbackConverter<>(branch.getSourceClass(), targetClass, branch, checked);
        }
    }

    /**
     * Merge {@code this} with an other converter whose target class is a subtype of
     * this {@link #targetClass}. If either {@link #fallback} or {@link #primary} are
     * other {@code FallbackConverter} instances, then this method will follow those
     * branches.
     *
     * @param  converter     the converter to merge with {@code this}.
     * @param  parentTarget  if this method is invoked recursively, the target class
     *         of the parent {@code FallbackConverter}. Otherwise {@code null}.
     * @return the merged converter.
     */
    private ObjectConverter<S, ? extends T> merge(final ObjectConverter<S, ? extends T> converter,
            final Class<? super T> parentTarget)
    {
        ObjectConverter<S, ? extends T> candidate;
        final ObjectConverter<S, ? extends T> newPrimary, newFallback;
        candidate = mergeIfSubtype(fallback, converter, targetClass);
        if (candidate != null) {
            newPrimary  = primary;
            newFallback = candidate;
        } else {
            candidate = mergeIfSubtype(primary, converter, targetClass);
            if (candidate != null) {
                newPrimary  = candidate;
                newFallback = fallback;
            } else if (targetClass != parentTarget) {
                newPrimary  = this;
                newFallback = converter;
            } else {
                /*
                 * If the we can not follow any of the 'primary' and 'fallback' branch,
                 * and if the target class of this FallbackConverter is the same than
                 * the target class of the parent, then do not create. We will let the
                 * parent FallbackConverter do the creation itself in order to chain the
                 * converters in the order they have been declared.
                 */
                return null;
            }
        }
        return new FallbackConverter<>(sourceClass, targetClass, newPrimary, newFallback);
    }

    /**
     * Returns the manner in which source values (<var>S</var>) are mapped to target values.
     * This is the intersection of the properties of the primary and fallback converters.
     */
    @Override
    public final Set<FunctionProperty> properties() {
        Set<FunctionProperty> properties = primary.properties();
        if (!(primary instanceof FallbackConverter<?,?>)) {
            properties = EnumSet.copyOf(properties);
            properties.remove(FunctionProperty.INVERTIBLE);
        }
        properties.retainAll(fallback.properties());
        return properties;
    }

    /**
     * Converts the given object, using the fallback if needed.
     */
    @Override
    public T apply(final S source) throws UnconvertibleObjectException {
        try {
            return primary.apply(source);
        } catch (UnconvertibleObjectException exception) {
            try {
                return fallback.apply(source);
            } catch (UnconvertibleObjectException failure) {
                exception.addSuppressed(failure);
                throw exception;
            }
        }
    }

    /**
     * Creates a node for the given converter and adds it to the given tree.
     * This method invokes itself recursively for scanning through fallbacks.
     *
     * @param  converter  the converter for which to create a tree.
     * @param  addTo      the node in which to add the converter.
     */
    private void toTree(final ObjectConverter<?,?> converter, TreeTable.Node addTo) {
        if (converter instanceof FallbackConverter<?,?>) {
            final boolean isNew = converter.getTargetClass() != targetClass;
            if (isNew) {
                addTo = addTo.newChild();
            }
            ((FallbackConverter<?,?>) converter).toTree(addTo, isNew);
        } else {
            Column.toTree(converter, addTo);
        }
    }

    /**
     * Adds a simplified tree representation of this {@code FallbackConverter} to the given node.
     *
     * @param  addTo  the node in which to add the converter.
     * @param  isNew  {@code true} if {@code addTo} is a newly created node.
     */
    final void toTree(final TreeTable.Node addTo, final boolean isNew) {
        if (isNew) {
            addTo.setValue(Column.SOURCE, sourceClass);
            addTo.setValue(Column.TARGET, targetClass);
        }
        toTree(primary,  addTo);
        toTree(fallback, addTo);
    }

    /**
     * Returns a tree representation of this converter.
     * The tree leaves represent the backing converters.
     */
    @Override
    public String toString() {
        final TreeTable table = Column.createTable();
        toTree(table.getRoot(), true);
        return Column.format(table);
    }
}
