/*
 * 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.rya.indexing.geotemporal;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.apache.rya.indexing.TemporalInstant;
import org.apache.rya.indexing.TemporalInstantRfc3339;
import org.apache.rya.indexing.external.matching.QuerySegment;
import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
import org.eclipse.rdf4j.query.algebra.FunctionCall;
import org.eclipse.rdf4j.query.algebra.QueryModelNode;
import org.eclipse.rdf4j.query.algebra.StatementPattern;
import org.eclipse.rdf4j.query.algebra.helpers.AbstractQueryModelVisitor;
import org.eclipse.rdf4j.query.algebra.helpers.StatementPatternCollector;
import org.eclipse.rdf4j.query.parser.sparql.SPARQLParser;
import org.junit.ComparisonFailure;
import org.mockito.Mockito;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.PrecisionModel;
import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence;

public final class GeoTemporalTestUtils {
    private static final GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);

    /**
     * Private constructor to prevent initialization.
     */
    private GeoTemporalTestUtils() { }

    /**
     * Make an uniform instant with given seconds.
     */
    public static TemporalInstant makeInstant(final int secondsMakeMeUnique) {
        return new TemporalInstantRfc3339(2015, 12, 30, 12, 00, secondsMakeMeUnique);
    }

    public static Polygon poly(final double[] arr) {
        final LinearRing r1 = gf.createLinearRing(new PackedCoordinateSequence.Double(arr, 2));
        final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {});
        return p1;
    }

    public static Point point(final double x, final double y) {
        return gf.createPoint(new Coordinate(x, y));
    }

    public static LineString line(final double x1, final double y1, final double x2, final double y2) {
        return new LineString(new PackedCoordinateSequence.Double(new double[] { x1, y1, x2, y2 }, 2), gf);
    }

    public static double[] bbox(final double x1, final double y1, final double x2, final double y2) {
        return new double[] { x1, y1, x1, y2, x2, y2, x2, y1, x1, y1 };
    }

    public static void assertEqualMongo(final Object expected, final Object actual) throws ComparisonFailure {
        try {
            assertEquals(expected, actual);
        } catch(final Throwable e) {
            throw new ComparisonFailure(e.getMessage(), expected.toString(), actual.toString());
        }
    }

    public static List<FunctionCall> getFilters(final String query) throws Exception {
        final FunctionCallCollector collector = new FunctionCallCollector();
        new SPARQLParser().parseQuery(query, null).getTupleExpr().visit(collector);
        return collector.getTupleExpr();
    }

    public static List<StatementPattern> getSps(final String query) throws Exception {
        final StatementPatternCollector collector = new StatementPatternCollector();
        new SPARQLParser().parseQuery(query, null).getTupleExpr().visit(collector);
        return collector.getStatementPatterns();
    }

    public static QuerySegment<EventQueryNode> getQueryNode(final String query) throws Exception {
        final List<QueryModelNode> exprs = getNodes(query);
        final QuerySegment<EventQueryNode> node = Mockito.mock(QuerySegment.class);
        //provider only cares about Ordered nodes.
        Mockito.when(node.getOrderedNodes()).thenReturn(exprs);
        return node;
    }

    private static List<QueryModelNode> getNodes(final String sparql) throws Exception {
        final NodeCollector collector = new NodeCollector();
        new SPARQLParser().parseQuery(sparql, null).getTupleExpr().visit(collector);
        return collector.getTupleExpr();
    }

    private static class NodeCollector extends AbstractQueryModelVisitor<RuntimeException> {
        private final List<QueryModelNode> stPatterns = new ArrayList<>();

        public List<QueryModelNode> getTupleExpr() {
            return stPatterns;
        }

        @Override
        public void meet(final FunctionCall node) {
            stPatterns.add(node);
        }

        @Override
        public void meet(final StatementPattern node) {
            stPatterns.add(node);
        }
    }

    private static class FunctionCallCollector extends AbstractQueryModelVisitor<RuntimeException> {
        private final List<FunctionCall> filters = new ArrayList<>();

        public List<FunctionCall> getTupleExpr() {
            return filters;
        }

        @Override
        public void meet(final FunctionCall node) {
            filters.add(node);
        }
    }
}
