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

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureType;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.expression.Function;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.feature.builder.FeatureTypeBuilder;
import org.apache.sis.referencing.crs.HardCodedCRS;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.test.TestCase;
import org.junit.Test;

import static org.opengis.test.Assert.*;


/**
 * Tests {@link SQLMM} functions implementations.
 * Current implementation tests Java Topology Suite (JTS) implementation only.
 *
 * @author  Johann Sorel (Geomatys)
 * @version 1.1
 * @since   1.1
 * @module
 */
public final strictfp class SQLMMTest extends TestCase {
    /**
     * The factory to use for creating the objects to test.
     */
    private final FilterFactory factory;

    /**
     * The factory to use for creating Java Topology Suite (JTS) objects.
     */
    private final GeometryFactory geometryFactory;

    /**
     * Creates a new test case.
     */
    public SQLMMTest() {
        factory = new DefaultFilterFactory();
        geometryFactory = new GeometryFactory();
    }

    /**
     * Verifies that attempts to create a function of the given name fail if no argument is provided.
     */
    private void assertRequireArguments(final String functionName) {
        try {
            factory.function(functionName);
            fail("Creation with no argument should fail");
        } catch (IllegalArgumentException ex) {
            final String message = ex.getMessage();
            assertTrue(message, message.contains("parameters"));
        }
    }

    /**
     * Wraps the given geometry in a feature object. The geometry will be stored in a property named {@code "geom"}.
     *
     * @param  geometry  the geometry to wrap in a feature.
     * @param  crs       the coordinate reference system to assign to the geometry.
     */
    private static Feature wrapInFeature(final Geometry geometry, final CoordinateReferenceSystem crs) {
        final FeatureTypeBuilder ftb = new FeatureTypeBuilder().setName("test");
        ftb.addAttribute(Point.class).setName("geom").setCRS(crs);
        final FeatureType type = ftb.build();
        geometry.setUserData(crs);
        final Feature feature = type.newInstance();
        feature.setPropertyValue("geom", geometry);
        return feature;
    }

    /**
     * Evaluates the given function and returns its result as an object of the given type.
     *
     * @param  expectedType  the expected type of the result.
     * @param  feature       the feature to use as input value. May be {@code null}.
     * @param  testing       the function to test.
     * @return evaluation result.
     */
    private static <G extends Geometry> G evaluate(final Class<G> expectedType, final Feature feature, final Function testing) {
        final Object result = testing.evaluate(feature);
        assertInstanceOf("Expected JTS geometry.", expectedType, result);
        return expectedType.cast(result);
    }

    /**
     * Test SQL/MM {@link ST_Transform} function.
     */
    @Test
    public void testTransform() {
        /*
         * Verify that creation of a function without arguments is not allowed.
         */
        assertRequireArguments("ST_Transform");
        /*
         * Create a feature to be used for testing purpose. For this test, the CRS transformation
         * will be simply a change of axis order from (λ,φ) to (φ,λ).
         */
        final Point geometry = geometryFactory.createPoint(new Coordinate(10, 30));
        final Feature feature = wrapInFeature(geometry, HardCodedCRS.WGS84);
        /*
         * Test transform function using the full CRS object, then using only EPSG code.
         */
        testTransform(feature, HardCodedCRS.WGS84_φλ, HardCodedCRS.WGS84_φλ);
        testTransform(feature, "EPSG:4326", CommonCRS.WGS84.geographic());
    }

    /**
     * Tests {@link ST_Transform} on the given feature. The feature must have a property named {@code "geom"}.
     * The result is expected to be a geometry using WGS84 datum with (φ,λ) axis order.
     *
     * @param  feature       the feature to use for testing the function.
     * @param  specifiedCRS  the argument to give to the {@code "ST_Transform"} function.
     * @param  expectedCRS   the CRS expected as a result of the transform function.
     */
    private void testTransform(final Feature feature, final Object specifiedCRS, final CoordinateReferenceSystem expectedCRS) {
        final Point result = evaluate(Point.class, feature, factory.function("ST_Transform",
                factory.property("geom"), factory.literal(specifiedCRS)));
        assertEquals("userData", expectedCRS, result.getUserData());
        assertEquals(30, result.getX(), STRICT);
        assertEquals(10, result.getY(), STRICT);
    }

    /**
     * Test SQL/MM {@link ST_Centroid} function.
     */
    @Test
    public void testCentroid() {
        assertRequireArguments("ST_Centroid");
        /*
         * Creates a single linestring for testing the centroid function. The CRS is not used by this computation,
         * but we declare it in order to verify that the information is propagated to the result.
         */
        final LineString geometry = geometryFactory.createLineString(new Coordinate[] {
            new Coordinate(10, 20),
            new Coordinate(30, 20)
        });
        geometry.setSRID(4326);
        geometry.setUserData(HardCodedCRS.WGS84_φλ);
        /*
         * Execute the function and check the result.
         */
        final Point result = evaluate(Point.class, null, factory.function("ST_Centroid", factory.literal(geometry)));
        assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
        assertEquals("SRID", 4326, result.getSRID());
        assertEquals(20, result.getX(), STRICT);
        assertEquals(20, result.getY(), STRICT);
    }

    /**
     * Test SQL/MM {@link ST_Buffer} function.
     */
    @Test
    public void ST_BufferTest() {
        assertRequireArguments("ST_Buffer");
        /*
         * Creates a single point for testing the buffer function. The CRS is not used by this computation,
         * but we declare it in order to verify that the information is propagated to the result.
         */
        final Point geometry = geometryFactory.createPoint(new Coordinate(10, 20));
        geometry.setUserData(HardCodedCRS.WGS84_φλ);
        geometry.setSRID(4326);
        /*
         * Execute the function and check the result.
         */
        final Polygon result = evaluate(Polygon.class, null, factory.function("ST_Buffer", factory.literal(geometry), factory.literal(1)));
        assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
        assertEquals("SRID", 4326, result.getSRID());
        final Envelope env = result.getEnvelopeInternal();
        assertEquals( 9, env.getMinX(), STRICT);
        assertEquals(11, env.getMaxX(), STRICT);
        assertEquals(19, env.getMinY(), STRICT);
        assertEquals(21, env.getMaxY(), STRICT);
    }
}
