/*
 * 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.Map;
import java.util.Collection;
import java.util.AbstractMap.SimpleEntry;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
import org.junit.Test;

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

// Branch-dependent imports
import org.opengis.feature.Attribute;


/**
 * Tests {@link CharacteristicMap} indirectly, through {@link AbstractAttribute} construction.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.5
 * @since   0.5
 * @module
 */
@DependsOn(CharacteristicTypeMapTest.class)
public final strictfp class CharacteristicMapTest extends TestCase {
    /**
     * Creates an attribute for a temperature measurement of 20°C with a ±0.1°C accuracy.
     *
     * @return a {@code "temperature"} attribute with two characteristics: {@code "accuracy"} and {@code "units"}.
     */
    public static AbstractAttribute<Float> temperature() {
        return new SingletonAttribute<>(CharacteristicTypeMapTest.temperature(), 20f);
    }

    /**
     * Creates an attribute for the given characteristic.
     *
     * @param  temperature  the attribute created by {@link #temperature()}.
     * @param  name         either {@code "accuracy"} or {@code "units"}.
     * @return an attribute for the given name.
     */
    private static AbstractAttribute<?> create(final AbstractAttribute<?> temperature, final String name) {
        return new SingletonAttribute<>(((DefaultAttributeType<?>) temperature.getType()).characteristics().get(name));
    }

    /**
     * Tests adding explicitly a characteristic with {@link CharacteristicMap#put(String, Attribute)}.
     */
    @Test
    public void testPut() {
        final AbstractAttribute<?>     temperature     = temperature();
        final AbstractAttribute<?>     units           = create(temperature, "units");
        final AbstractAttribute<?>     accuracy        = create(temperature, "accuracy");
        final Map<String,Attribute<?>> characteristics = temperature.characteristics();
        /*
         * Verify that the map is initially empty.
         */
        assertTrue  ("isEmpty",       characteristics.isEmpty());
        assertEquals("size", 0,       characteristics.size());
        assertFalse ("containsKey",   characteristics.containsKey("units"));
        assertFalse ("containsKey",   characteristics.containsKey("accuracy"));
        assertFalse ("containsKey",   characteristics.containsKey("temperature"));
        assertNull  ("get",           characteristics.get("units"));
        assertNull  ("get",           characteristics.get("accuracy"));
        assertNull  ("get",           characteristics.get("temperature"));
        assertFalse ("containsValue", characteristics.containsValue(units));
        assertFalse ("containsValue", characteristics.containsValue(accuracy));
        assertFalse ("containsValue", characteristics.containsValue(temperature));
        /*
         * Store "units" characteristic and verify.
         */
        assertNull  ("put",           characteristics.put("units", units));
        assertFalse ("isEmpty",       characteristics.isEmpty());
        assertEquals("size", 1,       characteristics.size());
        assertTrue  ("containsKey",   characteristics.containsKey("units"));
        assertFalse ("containsKey",   characteristics.containsKey("accuracy"));
        assertFalse ("containsKey",   characteristics.containsKey("temperature"));
        assertSame  ("get", units,    characteristics.get("units"));
        assertNull  ("get",           characteristics.get("accuracy"));
        assertNull  ("get",           characteristics.get("temperature"));
        assertTrue  ("containsValue", characteristics.containsValue(units));
        assertFalse ("containsValue", characteristics.containsValue(accuracy));
        assertFalse ("containsValue", characteristics.containsValue(temperature));
        /*
         * Store "accuracy" characteristic and verify.
         */
        assertNull  ("put",           characteristics.put("accuracy", accuracy));
        assertFalse ("isEmpty",       characteristics.isEmpty());
        assertEquals("size", 2,       characteristics.size());
        assertTrue  ("containsKey",   characteristics.containsKey("units"));
        assertTrue  ("containsKey",   characteristics.containsKey("accuracy"));
        assertFalse ("containsKey",   characteristics.containsKey("temperature"));
        assertSame  ("get", units,    characteristics.get("units"));
        assertSame  ("get", accuracy, characteristics.get("accuracy"));
        assertNull  ("get",           characteristics.get("temperature"));
        assertTrue  ("containsValue", characteristics.containsValue(units));
        assertTrue  ("containsValue", characteristics.containsValue(accuracy));
        assertFalse ("containsValue", characteristics.containsValue(temperature));
        /*
         * Overwrite values. Map shall stay unchanged.
         */
        assertSame  ("put",  accuracy, characteristics.put("accuracy", accuracy));
        assertSame  ("put",  units,    characteristics.put("units",    units));
        assertEquals("size", 2,        characteristics.size());
        /*
         * Try putting an attribute for a non-existent name.
         * Map shall stay unchanged.
         */
        try {
            characteristics.put("dummy", units);
            fail("Operation shall not have been allowed.");
        } catch (IllegalArgumentException e) {
            final String message = e.getMessage();
            assertTrue(message, message.contains("dummy"));       // Message shall contain the wrong name.
            assertTrue(message, message.contains("temperature")); // Message shall contain the enclosing attribute name.
        }
        /*
         * Try putting an attribute of the wrong type.
         * Map shall stay unchanged.
         */
        try {
            characteristics.put("units", accuracy);
            fail("Operation shall not have been allowed.");
        } catch (IllegalArgumentException e) {
            final String message = e.getMessage();
            assertTrue(message, message.contains("accuracy"));
            assertTrue(message, message.contains("temperature:units"));
        }
        assertEntriesEqual(units, accuracy, characteristics);
        assertSame(characteristics, temperature.characteristics());
    }

    /**
     * Tests adding a characteristic indirectly with {@link CharacteristicMap#addValue(Attribute)}.
     */
    @Test
    @DependsOnMethod("testPut")
    public void testAddValue() {
        final AbstractAttribute<?>     temperature     = temperature();
        final AbstractAttribute<?>     units           = create(temperature, "units");
        final AbstractAttribute<?>     accuracy        = create(temperature, "accuracy");
        final Map<String,Attribute<?>> characteristics = temperature.characteristics();
        final Collection<Attribute<?>> values          = characteristics.values();
        /*
         * Verify that the collection is initially empty.
         */
        assertTrue  ("isEmpty",  values.isEmpty());
        assertEquals("size", 0,  values.size());
        assertFalse ("contains", values.contains(units));
        assertFalse ("contains", values.contains(accuracy));
        assertFalse ("contains", values.contains(temperature));
        /*
         * Store "units" characteristic and verify.
         */
        assertTrue  ("add",      values.add(units));
        assertFalse ("isEmpty",  values.isEmpty());
        assertEquals("size", 1,  values.size());
        assertTrue  ("contains", values.contains(units));
        assertFalse ("contains", values.contains(accuracy));
        assertFalse ("contains", values.contains(temperature));
        /*
         * Store "accuracy" characteristic and verify.
         */
        assertTrue  ("add",      values.add(accuracy));
        assertFalse ("isEmpty",  values.isEmpty());
        assertEquals("size", 2,  values.size());
        assertTrue  ("contains", values.contains(units));
        assertTrue  ("contains", values.contains(accuracy));
        assertFalse ("contains", values.contains(temperature));
        /*
         * Overwrite values. Map shall stay unchanged.
         */
        assertFalse ("add",     values.add(accuracy));
        assertFalse ("add",     values.add(units));
        assertEquals("size", 2, values.size());
        /*
         * Try adding an attribute of the wrong type.
         * Map shall stay unchanged.
         */
        try {
            values.add(temperature);
            fail("Operation shall not have been allowed.");
        } catch (IllegalArgumentException e) {
            final String message = e.getMessage();
            assertTrue(message, message.contains("temperature"));
        }
        assertEntriesEqual(units, accuracy, characteristics);
        assertSame(characteristics, temperature.characteristics());
    }

    /**
     * Tests adding a characteristic indirectly with {@link CharacteristicMap#addKey(String)}.
     */
    @Test
    @DependsOnMethod("testPut")
    public void testAddKey() {
        final Attribute<?> units, accuracy;
        final AbstractAttribute<?>     temperature     = temperature();
        final Map<String,Attribute<?>> characteristics = temperature.characteristics();
        final Collection<String>       keys            = characteristics.keySet();
        /*
         * Verify that the collection is initially empty.
         */
        assertTrue  ("isEmpty",  keys.isEmpty());
        assertEquals("size", 0,  keys.size());
        assertFalse ("contains", keys.contains("units"));
        assertFalse ("contains", keys.contains("accuracy"));
        assertFalse ("contains", keys.contains("temperature"));
        /*
         * Store "units" characteristic and verify.
         */
        assertTrue   ("add",      keys.add("units"));
        assertFalse  ("isEmpty",  keys.isEmpty());
        assertEquals ("size", 1,  keys.size());
        assertTrue   ("contains", keys.contains("units"));
        assertFalse  ("contains", keys.contains("accuracy"));
        assertFalse  ("contains", keys.contains("temperature"));
        assertNotNull("get",      units = characteristics.get("units"));
        /*
         * Store "accuracy" characteristic and verify.
         */
        assertTrue  ("add",       keys.add("accuracy"));
        assertFalse ("isEmpty",   keys.isEmpty());
        assertEquals("size", 2,   keys.size());
        assertTrue  ("contains",  keys.contains("units"));
        assertTrue  ("contains",  keys.contains("accuracy"));
        assertFalse ("contains",  keys.contains("temperature"));
        assertNotNull("get",      accuracy = characteristics.get("accuracy"));
        /*
         * Overwrite values. Map shall stay unchanged.
         */
        assertFalse ("add",     keys.add("accuracy"));
        assertFalse ("add",     keys.add("units"));
        assertEquals("size", 2, keys.size());
        /*
         * Try adding an attribute of the wrong type.
         * Map shall stay unchanged.
         */
        try {
            keys.add("dummy");
            fail("Operation shall not have been allowed.");
        } catch (IllegalArgumentException e) {
            final String message = e.getMessage();
            assertTrue(message, message.contains("temperature"));
            assertTrue(message, message.contains("dummy"));
        }
        assertEntriesEqual(units, accuracy, characteristics);
        assertSame(characteristics, temperature.characteristics());
    }

    /**
     * Verifies that the given characteristics map contains entries for the given attributes.
     *
     * @param  units            the first expected value in iteration order.
     * @param  accuracy         the second expected value in iteration order.
     * @param  characteristics  the map to verify.
     */
    private static void assertEntriesEqual(final Attribute<?> units, final Attribute<?> accuracy,
            final Map<String,Attribute<?>> characteristics)
    {
        assertArrayEquals("keySet", new String[] {"accuracy", "units"}, characteristics.keySet().toArray());
        assertArrayEquals("values", new Object[] { accuracy ,  units }, characteristics.values().toArray());
        assertArrayEquals("entrySet", new Object[] {
                new SimpleEntry<>("accuracy", accuracy),
                new SimpleEntry<>("units",    units)
            }, characteristics.entrySet().toArray());
    }

    /**
     * Sets the accuracy characteristic in the given attribute.
     *
     * @param  temperature  the attribute where to set the accuracy.
     * @param  isFirstTime  {@code true} if the accuracy value is set for the first time.
     * @param  value        the new accuracy value.
     */
    private static void setAccuracy(final AbstractAttribute<Float> temperature, final boolean isFirstTime, final float value) {
        assertEquals("keySet.add", isFirstTime, temperature.characteristics().keySet().add("accuracy"));
        final Attribute<Float> accuracy = Features.cast(temperature.characteristics().get("accuracy"), Float.class);
        accuracy.setValue(value);
    }

    /**
     * Tests {@link CharacteristicMap#equals(Object)} and (opportunistically) {@link CharacteristicMap#clone()}
     */
    @Test
    @DependsOnMethod("testAddKey")
    public void testEquals() {
        final AbstractAttribute<Float> t1 = temperature();
        final AbstractAttribute<Float> t2 = temperature();
        assertEquals("equals",   t1, t2);
        assertEquals("hashCode", t1.hashCode(), t2.hashCode());
        setAccuracy(t1, true, 0.2f);
        assertFalse("equals",   t1.equals(t2));
        assertFalse("equals",   t2.equals(t1));
        assertFalse("hashCode", t1.hashCode() == t2.hashCode());
        setAccuracy(t2, true, 0.3f);
        assertFalse("equals",   t1.equals(t2));
        assertFalse("equals",   t2.equals(t1));
        assertFalse("hashCode", t1.hashCode() == t2.hashCode());
        setAccuracy(t1, false, 0.3f);
        assertEquals("equals",   t1, t2);
        assertEquals("hashCode", t1.hashCode(), t2.hashCode());
    }

    /**
     * Tests the reconstruction of {@link CharacteristicTypeMap} after serialization.
     */
    @Test
    @DependsOnMethod({"testEquals", "testAddValue"})            // Implementation of readObject use values().addAll(…).
    public void testSerialization() {
        final AbstractAttribute<Float> temperature = temperature();
        setAccuracy(temperature, true, 0.2f);

        final AbstractAttribute<Float> unserialized = assertSerializedEquals(temperature);
        assertNotSame(temperature, unserialized);
        assertNotSame(temperature.characteristics(), unserialized.characteristics());
        assertSame(((DefaultAttributeType<?>) temperature .getType()).characteristics(),
                   ((DefaultAttributeType<?>) unserialized.getType()).characteristics());
    }
}
