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

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.sis.test.DependsOn;

import static org.apache.sis.test.Assert.*;


/**
 * Tests some default method implementations provided in {@link AbstractFeature}.
 * This test also has the side-effect of testing {@link Validator} with attribute
 * instances that are not {@link AbstractAttribute}.
 *
 * <p>This class inherits all tests defined in {@link FeatureTestCase}.</p>
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 * @since   0.8
 * @module
 */
@DependsOn({
    DenseFeatureTest.class,
    SparseFeatureTest.class
})
public final strictfp class AbstractFeatureTest extends FeatureTestCase {
    /**
     * A feature implementation on top of {@link AbstractFeature}. This class has more code than strictly necessary
     * since we need to reproduce some of the verifications performed by the Apache SIS supported implementations
     * in order to get the tests to pass.
     */
    @SuppressWarnings("serial")
    private static final class CustomFeature extends AbstractFeature implements Cloneable {
        /**
         * All property values. For this test we use a {@code java.util.Map}. However users who want to provide
         * their own {@link AbstractFeature} implementation should consider to use plain Java fields instead.
         * If a feature backed by a {@code java.util.Map} is really wanted, then {@link SparseFeature} should
         * be considered.
         */
        private HashMap<String,Object> values = new HashMap<>();

        /**
         * Creates a new feature of the given type. This constructor adds immediately the default values into
         * the {@link #values} map and a modifiable list (even if empty) for all properties that are collections.
         */
        CustomFeature(final DefaultFeatureType type) {
            super(type);
            for (final AbstractIdentifiedType pt : type.getProperties(true)) {
                if (pt instanceof DefaultAttributeType<?>) {
                    Object value = ((DefaultAttributeType<?>) pt).getDefaultValue();
                    if (isMultiValued(pt)) {
                        value = new ArrayList<>(PropertyView.singletonOrEmpty(value));
                    }
                    if (value != null) {
                        values.put(pt.getName().toString(), value);
                    }
                }
            }
        }

        /**
         * Returns {@code true} if the given property can contains more than one value.
         */
        private static boolean isMultiValued(final AbstractIdentifiedType pt) {
            return (pt instanceof DefaultAttributeType<?>) && (((DefaultAttributeType<?>) pt).getMaximumOccurs() > 1);
        }

        /**
         * Returns the value for the property of the given name, or {@code null} if none.
         * This method does not verify if it should return the default value or a collection.
         * In this simple implementation, those verifications are done at construction time.
         *
         * <p>A robust implementation would verify that the given name is legal.
         * For this test, be skip that verification.</p>
         */
        @Override
        public Object getPropertyValue(final String name) {
            return values.get(name);
        }

        /**
         * Sets the value for the property of the given name. In order to allow the tests to pass,
         * we need to reproduce in this method some of the verifications performed by the
         * {@link SingletonAttribute} and {@link MultiValuedAttribute} implementations.
         */
        @Override
        public void setPropertyValue(final String name, Object value) {
            final AbstractIdentifiedType type = getType().getProperty(name);
            final boolean isMultiValued = isMultiValued(type);
            if (isMultiValued && !(value instanceof Collection<?>)) {
                value = new ArrayList<>(PropertyView.singletonOrEmpty(value));
            }
            if (value != null) {
                final Class<?> base;
                if (type instanceof DefaultAttributeType<?>) {
                    base = ((DefaultAttributeType<?>) type).getValueClass();
                } else {
                    base = FeatureType.class;
                }
                for (final Object element : (isMultiValued ? (Iterable<?>) value : PropertyView.singletonOrEmpty(value))) {
                    if (!base.isInstance(element)) {
                        throw new ClassCastException("Can not cast " + value.getClass() + " to " + base + " in " + name + '.');
                    }
                }
            }
            values.put(name, value);
        }

        /**
         * Returns a close of this feature.
         */
        @Override
        @SuppressWarnings("unchecked")
        public CustomFeature clone() {
            final CustomFeature c;
            try {
                c = (CustomFeature) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new AssertionError(e);
            }
            c.values = (HashMap<String,Object>) c.values.clone();
            return c;
        }
    }

    /**
     * Relax the requirements about {@link AbstractFeature#getProperty(String)} to return the exact same instance.
     */
    @Override
    boolean assertSameProperty(final String name, final Property expected, final boolean modified) {
        final Property actual = (Property) feature.getProperty(name);
        assertSame("name", expected.getName(), actual.getName());
        if (!modified) {
            assertSame("value", expected.getValue(), actual.getValue());
        }
        return actual == expected;
    }

    /**
     * Creates a new feature for the given type.
     */
    @Override
    final AbstractFeature createFeature(final DefaultFeatureType type) {
        return new CustomFeature(type);
    }

    /**
     * Clones the {@link #feature} instance.
     */
    @Override
    final AbstractFeature cloneFeature() throws CloneNotSupportedException {
        return ((CustomFeature) feature).clone();
    }

    // Inherit all tests from the super-class.
}
