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

import java.util.Iterator;
import java.util.Collections;
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.Point;
import org.opengis.geometry.Envelope;
import org.apache.sis.feature.AbstractOperation;
import org.apache.sis.internal.feature.AttributeConvention;
import org.apache.sis.feature.DefaultFeatureTypeTest;
import org.apache.sis.feature.FeatureOperations;
import org.apache.sis.referencing.crs.HardCodedCRS;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestUtilities;
import org.apache.sis.test.TestCase;
import org.junit.Test;

import static org.junit.Assert.*;

// Branch-dependent imports
import org.apache.sis.feature.AbstractIdentifiedType;
import org.apache.sis.feature.DefaultAttributeType;
import org.apache.sis.feature.DefaultFeatureType;


/**
 * Tests {@link FeatureTypeBuilder}.
 *
 * @author  Johann Sorel (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @author  Michael Hausegger
 * @version 0.8
 * @since   0.8
 * @module
 */
@DependsOn(AttributeTypeBuilderTest.class)
public final strictfp class FeatureTypeBuilderTest extends TestCase {
    /**
     * Verifies that {@code FeatureTypeBuilder.setSuperTypes(FeatureType...)} ignores null parents.
     * This method tests only the builder state without creating feature type.
     */
    @Test
    public void testNullParents() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder(null);
        assertSame(builder, builder.setSuperTypes(new DefaultFeatureType[6]));
        assertEquals(0, builder.getSuperTypes().length);
    }

    /**
     * Verifies {@link FeatureTypeBuilder#setAbstract(boolean)}.
     * This method tests only the builder state without creating feature type.
     */
    @Test
    public void testSetAbstract() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder(null);
        assertFalse("isAbstract", builder.isAbstract());
        assertSame (builder, builder.setAbstract(true));
        assertTrue ("isAbstract", builder.isAbstract());
    }

    /**
     * Verifies {@link FeatureTypeBuilder#setDeprecated(boolean)}.
     * This method tests only the builder state without creating feature type.
     */
    @Test
    public void testSetDeprecated() {
        FeatureTypeBuilder builder = new FeatureTypeBuilder();
        assertFalse("isDeprecated", builder.isDeprecated());
        builder.setDeprecated(true);
        assertTrue("isDeprecated", builder.isDeprecated());
    }

    /**
     * Verifies {@link FeatureTypeBuilder#setNameSpace(CharSequence)}.
     */
    @Test
    public void testSetNameSpace() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder();
        assertNull("nameSpace", builder.getNameSpace());
        assertSame(builder, builder.setNameSpace("myNameSpace"));
        assertEquals("nameSpace", "myNameSpace", builder.getNameSpace());
    }

    /**
     * Tests with the minimum number of parameters (no property and no super type).
     */
    @Test
    @DependsOnMethod({"testSetAbstract", "testSetDeprecated", "testSetNameSpace"})
    public void testInitialization() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder();
        try {
            builder.build();
            fail("Builder should have failed if there is not at least a name set.");
        } catch (IllegalArgumentException ex) {
            final String message = ex.getMessage();
            assertTrue(message, message.contains("name"));
        }
        assertSame(builder, builder.setName("scope", "test"));
        final DefaultFeatureType type = builder.build();

        assertEquals("name", "scope:test",   type.getName().toString());
        assertFalse ("isAbstract",           type.isAbstract());
        assertEquals("properties count",  0, type.getProperties(true).size());
        assertEquals("super-types count", 0, type.getSuperTypes().size());
    }

    /**
     * Tests {@link FeatureTypeBuilder#addAttribute(Class)}.
     */
    @Test
    @DependsOnMethod("testInitialization")
    public void testAddAttribute() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder();
        assertSame(builder, builder.setName("myScope", "myName"));
        assertSame(builder, builder.setDefinition ("test definition"));
        assertSame(builder, builder.setDesignation("test designation"));
        assertSame(builder, builder.setDescription("test description"));
        assertSame(builder, builder.setAbstract(true));
        builder.addAttribute(String .class).setName("name");
        builder.addAttribute(Integer.class).setName("age");
        builder.addAttribute(Point  .class).setName("location").setCRS(HardCodedCRS.WGS84);
        builder.addAttribute(Double .class).setName("score").setDefaultValue(10.0).setMinimumOccurs(5).setMaximumOccurs(50);

        final DefaultFeatureType type = builder.build();
        assertEquals("name",        "myScope:myName",   type.getName().toString());
        assertEquals("definition",  "test definition",  type.getDefinition().toString());
        assertEquals("description", "test description", type.getDescription().toString());
        assertEquals("designation", "test designation", type.getDesignation().toString());
        assertTrue  ("isAbstract",                      type.isAbstract());

        final Iterator<? extends AbstractIdentifiedType> it = type.getProperties(true).iterator();
        final DefaultAttributeType<?> a0 = (DefaultAttributeType<?>) it.next();
        final DefaultAttributeType<?> a1 = (DefaultAttributeType<?>) it.next();
        final DefaultAttributeType<?> a2 = (DefaultAttributeType<?>) it.next();
        final DefaultAttributeType<?> a3 = (DefaultAttributeType<?>) it.next();
        assertFalse("properties count", it.hasNext());

        assertEquals("name", "name",     a0.getName().toString());
        assertEquals("name", "age",      a1.getName().toString());
        assertEquals("name", "location", a2.getName().toString());
        assertEquals("name", "score",    a3.getName().toString());

        assertEquals("valueClass", String.class,  a0.getValueClass());
        assertEquals("valueClass", Integer.class, a1.getValueClass());
        assertEquals("valueClass", Point.class,   a2.getValueClass());
        assertEquals("valueClass", Double.class,  a3.getValueClass());

        assertEquals("minimumOccurs",   1, a0.getMinimumOccurs());
        assertEquals("minimumOccurs",   1, a1.getMinimumOccurs());
        assertEquals("minimumOccurs",   1, a2.getMinimumOccurs());
        assertEquals("minimumOccurs",   5, a3.getMinimumOccurs());

        assertEquals("maximumOccurs",   1, a0.getMaximumOccurs());
        assertEquals("maximumOccurs",   1, a1.getMaximumOccurs());
        assertEquals("maximumOccurs",   1, a2.getMaximumOccurs());
        assertEquals("maximumOccurs",  50, a3.getMaximumOccurs());

        assertEquals("defaultValue", null, a0.getDefaultValue());
        assertEquals("defaultValue", null, a1.getDefaultValue());
        assertEquals("defaultValue", null, a2.getDefaultValue());
        assertEquals("defaultValue", 10.0, a3.getDefaultValue());

        assertFalse("characterizedByCRS", AttributeConvention.characterizedByCRS(a0));
        assertFalse("characterizedByCRS", AttributeConvention.characterizedByCRS(a1));
        assertTrue ("characterizedByCRS", AttributeConvention.characterizedByCRS(a2));
        assertFalse("characterizedByCRS", AttributeConvention.characterizedByCRS(a3));
    }

    /**
     * Tests {@link FeatureTypeBuilder#addAttribute(Class)} where one property is an identifier
     * and another property is the geometry.
     */
    @Test
    @DependsOnMethod("testAddAttribute")
    public void testAddIdentifierAndGeometry() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder();
        assertSame(builder, builder.setName("scope", "test"));
        assertSame(builder, builder.setIdentifierDelimiters("-", "pref.", null));
        builder.addAttribute(String.class).setName("name")
                .addRole(AttributeRole.IDENTIFIER_COMPONENT);
        builder.addAttribute(Geometry.class).setName("shape")
                .setCRS(HardCodedCRS.WGS84)
                .addRole(AttributeRole.DEFAULT_GEOMETRY);

        final DefaultFeatureType type = builder.build();
        assertEquals("name", "scope:test", type.getName().toString());
        assertFalse ("isAbstract", type.isAbstract());

        final Iterator<? extends AbstractIdentifiedType> it = type.getProperties(true).iterator();
        final AbstractIdentifiedType a0 = it.next();
        final AbstractIdentifiedType a1 = it.next();
        final AbstractIdentifiedType a2 = it.next();
        final AbstractIdentifiedType a3 = it.next();
        final AbstractIdentifiedType a4 = it.next();
        assertFalse("properties count", it.hasNext());

        assertEquals("name", AttributeConvention.IDENTIFIER_PROPERTY, a0.getName());
        assertEquals("name", AttributeConvention.ENVELOPE_PROPERTY,   a1.getName());
        assertEquals("name", AttributeConvention.GEOMETRY_PROPERTY,   a2.getName());
        assertEquals("name", "name",                                  a3.getName().toString());
        assertEquals("name", "shape",                                 a4.getName().toString());
    }

    /**
     * Tests {@link FeatureTypeBuilder#addAttribute(Class)} where one attribute is an identifier that already has
     * the {@code "sis:identifier"} name. This is called "anonymous" because identifiers with an explicit name in
     * the data file should use that name instead in the feature type.
     */
    @Test
    @DependsOnMethod("testAddIdentifierAndGeometry")
    public void testAddAnonymousIdentifier() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder();
        assertSame(builder, builder.setName("City"));
        builder.addAttribute(String.class).setName(AttributeConvention.IDENTIFIER_PROPERTY).addRole(AttributeRole.IDENTIFIER_COMPONENT);
        builder.addAttribute(Integer.class).setName("population");
        final DefaultFeatureType type = builder.build();
        final Iterator<? extends AbstractIdentifiedType> it = type.getProperties(true).iterator();
        final AbstractIdentifiedType a0 = it.next();
        final AbstractIdentifiedType a1 = it.next();
        assertFalse("properties count", it.hasNext());
        assertEquals("name", AttributeConvention.IDENTIFIER_PROPERTY, a0.getName());
        assertEquals("type", String.class,  ((DefaultAttributeType<?>) a0).getValueClass());
        assertEquals("name", "population", a1.getName().toString());
        assertEquals("type", Integer.class, ((DefaultAttributeType<?>) a1).getValueClass());
    }

    /**
     * Tests {@link FeatureTypeBuilder#addAttribute(Class)} where one attribute is a geometry that already has
     * the {@code "sis:geometry"} name. This is called "anonymous" because geometries with an explicit name in
     * the data file should use that name instead in the feature type.
     */
    @Test
    @DependsOnMethod("testAddIdentifierAndGeometry")
    public void testAddAnonymousGeometry() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder();
        assertSame(builder, builder.setName("City"));
        builder.addAttribute(Point.class).setName(AttributeConvention.GEOMETRY_PROPERTY).addRole(AttributeRole.DEFAULT_GEOMETRY);
        builder.addAttribute(Integer.class).setName("population");
        final DefaultFeatureType type = builder.build();
        final Iterator<? extends AbstractIdentifiedType> it = type.getProperties(true).iterator();
        final AbstractIdentifiedType a0 = it.next();
        final AbstractIdentifiedType a1 = it.next();
        final AbstractIdentifiedType a2 = it.next();
        assertFalse("properties count", it.hasNext());
        assertEquals("name", AttributeConvention.ENVELOPE_PROPERTY, a0.getName());
        assertEquals("name", AttributeConvention.GEOMETRY_PROPERTY, a1.getName());
        assertEquals("type", Point.class,   ((DefaultAttributeType<?>) a1).getValueClass());
        assertEquals("name", "population", a2.getName().toString());
        assertEquals("type", Integer.class, ((DefaultAttributeType<?>) a2).getValueClass());
    }

    /**
     * Tests creation of a builder from an existing feature type.
     * This method also acts as a test of {@code FeatureTypeBuilder} getter methods.
     */
    @Test
    public void testCreateFromTemplate() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder(DefaultFeatureTypeTest.capital());
        assertEquals("name",       "Capital", builder.getName().toString());
        assertEquals("superTypes", "City",    TestUtilities.getSingleton(builder.getSuperTypes()).getName().toString());
        assertFalse ("isAbstract",            builder.isAbstract());

        // The list of properties does not include super-type properties.
        final AttributeTypeBuilder<?> a0 = (AttributeTypeBuilder<?>) TestUtilities.getSingleton(builder.properties());
        assertEquals("name",  "parliament",  a0.getName().toString());
        assertEquals("type",  String.class,  a0.getValueClass());
        assertTrue  ("roles",                a0.roles().isEmpty());
    }

    /**
     * Tests creation of a builder from an existing feature type with some attributes having {@link AttributeRole}s.
     */
    @Test
    @DependsOnMethod("testCreateFromTemplate")
    public void testCreateFromTemplateWithRoles() {
        FeatureTypeBuilder builder = new FeatureTypeBuilder().setName("City");
        builder.addAttribute(String  .class).setName("name").roles().add(AttributeRole.IDENTIFIER_COMPONENT);
        builder.addAttribute(Integer .class).setName("population");
        builder.addAttribute(Geometry.class).setName("area").roles().add(AttributeRole.DEFAULT_GEOMETRY);

        final DefaultFeatureType type = builder.build();
        builder = new FeatureTypeBuilder(type);
        assertEquals("name", "City", builder.getName().toString());
        assertEquals("superTypes", 0, builder.getSuperTypes().length);

        final Iterator<PropertyTypeBuilder> it = builder.properties().iterator();
        final AttributeTypeBuilder<?> a0 = (AttributeTypeBuilder<?>) it.next();
        final AttributeTypeBuilder<?> a1 = (AttributeTypeBuilder<?>) it.next();
        final AttributeTypeBuilder<?> a2 = (AttributeTypeBuilder<?>) it.next();
        assertFalse("properties count", it.hasNext());
        assertEquals("name", "name",       a0.getName().toString());
        assertEquals("name", "population", a1.getName().toString());
        assertEquals("name", "area",       a2.getName().toString());

        assertEquals("type", String.class,   a0.getValueClass());
        assertEquals("type", Integer.class,  a1.getValueClass());
        assertEquals("type", Geometry.class, a2.getValueClass());

        assertTrue  ("roles", a1.roles().isEmpty());
        assertEquals("roles", AttributeRole.IDENTIFIER_COMPONENT, TestUtilities.getSingleton(a0.roles()));
        assertEquals("roles", AttributeRole.DEFAULT_GEOMETRY,     TestUtilities.getSingleton(a2.roles()));
    }

    /**
     * Verifies that {@code build()} method returns the previously created instance when possible.
     * See {@link AttributeTypeBuilder#build()} javadoc for a rational.
     */
    @Test
    @DependsOnMethod("testAddAttribute")
    public void testBuildCache() {
        final FeatureTypeBuilder builder = new FeatureTypeBuilder().setName("City");
        final DefaultAttributeType<String> name = builder.addAttribute(String.class).setName("name").build();
        final DefaultFeatureType city = builder.build();
        assertSame("Should return the existing AttributeType.", name, city.getProperty("name"));
        assertSame("Should return the existing FeatureType.", city, builder.build());

        assertSame("Should return the existing AttributeType since we didn't changed anything.",
                   name, builder.getProperty("name").build());

        assertNotSame("Should return a new AttributeType since we changed something.",
                      name, builder.getProperty("name").setDescription("Name of the city").build());

        assertNotSame("Should return a new FeatureType since we changed an attribute.",
                      city, builder.build());
    }

    /**
     * Tests overriding the "sis:envelope" property. This may happen when the user wants to specify
     * envelope himself instead than relying on the automatically computed value.
     */
    @Test
    public void testEnvelopeOverride() {
        FeatureTypeBuilder builder = new FeatureTypeBuilder().setName("CoverageRecord").setAbstract(true);
        builder.addAttribute(Geometry.class).setName(AttributeConvention.GEOMETRY_PROPERTY).addRole(AttributeRole.DEFAULT_GEOMETRY);
        final DefaultFeatureType parentType = builder.build();

        builder = new FeatureTypeBuilder().setName("Record").setSuperTypes(parentType);
        builder.addAttribute(Envelope.class).setName(AttributeConvention.ENVELOPE_PROPERTY);
        final DefaultFeatureType childType = builder.build();

        final Iterator<? extends AbstractIdentifiedType> it = childType.getProperties(true).iterator();
        assertPropertyEquals("sis:envelope", Envelope.class, it.next());
        assertPropertyEquals("sis:geometry", Geometry.class, it.next());
        assertFalse(it.hasNext());
    }

    /**
     * Tests overriding an attribute by an operation.
     * This is the converse of {@link #testEnvelopeOverride()}.
     */
    @Test
    public void testOverrideByOperation() {
        FeatureTypeBuilder builder = new FeatureTypeBuilder().setName("Parent").setAbstract(true);
        final DefaultAttributeType<Integer> pa = builder.addAttribute(Integer.class).setName("A").build();
        builder.addAttribute(Integer.class).setName("B");
        final DefaultFeatureType parentType = builder.build();

        builder = new FeatureTypeBuilder().setName("Child").setSuperTypes(parentType);
        builder.addProperty(FeatureOperations.link(Collections.singletonMap(AbstractOperation.NAME_KEY, "B"), pa));
        final DefaultFeatureType childType = builder.build();

        final Iterator<? extends AbstractIdentifiedType> it = childType.getProperties(true).iterator();
        assertPropertyEquals("A", Integer.class, it.next());
        assertPropertyEquals("B", Integer.class, it.next());
        assertFalse(it.hasNext());
    }

    /**
     * Verifies that the given property is an attribute with the given name and value class.
     */
    private static void assertPropertyEquals(final String name, final Class<?> valueClass, AbstractIdentifiedType property) {
        assertEquals("name", name, property.getName().toString());
        if (property instanceof AbstractOperation) {
            property = ((AbstractOperation) property).getResult();
        }
        assertEquals("valueClass", valueClass, ((DefaultAttributeType<?>) property).getValueClass());
    }
}
