/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.expressions.spatial;

import java.util.List;
import java.util.Vector;

import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.internal.expressions.FunctionExpression;

import static org.eclipse.persistence.expressions.ExpressionOperator.SDO_WITHIN_DISTANCE;
import static org.eclipse.persistence.expressions.ExpressionOperator.SDO_RELATE;
import static org.eclipse.persistence.expressions.ExpressionOperator.SDO_FILTER;
import static org.eclipse.persistence.expressions.ExpressionOperator.SDO_NN;

/**
 * This class is used to construct expressions that use Oracle Spatial operators
 *
 * <blockquote><pre>
 * ExpressionBuilder builder = new ExpressionBuilder();
 * Expression withinDistance = SpatialExpressions.withinDistance(myJGeometry1, myJGeometry2, "DISTANCE=10");
 * session.readAllObjects(GeometryHolder.class, withinDistance);
 * </pre></blockquote>
 *
 * @since Oracle TopLink 11.1.1.0.0
 */
public final class SpatialExpressionFactory {

    private SpatialExpressionFactory() {
        // no instance please
    }

    /**
     * PUBLIC:
     * Return an Expression for the MDSYS.SDO_WITHIN_DISTANCE Spatial Operator on the Oracle Database
     * Use of this expression requires the Java spatial classes
     *
     * <blockquote><pre>
     * SpatialParameters parameters = new SpatialParameters();
     *parameters.setDistance(10d);
     * Expression selectCriteria = SpatialExpressions.withinDistance(jGeometry1, jGeometry2, parameters);
     * </pre></blockquote>
     *
     * @param geom1 an Expression representing a JGeometryObject
     * @param geom2 a JGeometryObject or an Expression representing a JGeometryObject
     * @param params a SpatialParameters object configured with the parameters to the call
     * @return a TopLink Expression
     */
    public static Expression withinDistance(Expression geom1, Object geom2, SpatialParameters params) {
        String stringParameters = params == null ? null : params.getParameterString();
        return getSpatialExpression(SDO_WITHIN_DISTANCE, geom1, geom2, stringParameters);
    }

    /**
     * PUBLIC:
     * Return an Expression for the MDSYS.MDSYS.SDO_RELATE Spatial Operator on the Oracle Database
     * Use of this operator requires the Java spatial classes
     *
     * <blockquote><pre>
     * SpatialParameters parameters = new SpatialParameters();
     * parameters..setMask(Mask.ANYINTERACT).setQueryType(QueryType.WINDOW);
     * Expression selectCriteria = SpatialExpressions.relate(jGeometry1, jGeometry2, parameters);
     * </pre></blockquote>
     *
     * @param geom1 an Expression representing a JGeometryObject
     * @param geom2 a JGeometryObject or an Expression representing a JGeometryObject
     * @param params a SpatialParameters object configured with the parameters to the call
     * @return a TopLink Expression
     */
    public static Expression relate(Expression geom1, Object geom2, SpatialParameters params) {
        String stringParameters = params == null ? null : params.getParameterString();
        return getSpatialExpression(SDO_RELATE, geom1, geom2, stringParameters);
    }

    /**
     * PUBLIC:
     * Return an Expression for the MDSYS.SDO_FILTER Spatial Operator on the Oracle Database
     * Use of this operator requires the Java spatial classes
     *
     * <blockquote><pre>
     * SpatialParameters parameters = new SpatialParameters();
     * parameters.setQueryType(QueryType.WINDOW);
     * Expression selectCriteria = SpatialExpressions.filter(jGeometry1, jGeometry2, parameters);
     * </pre></blockquote>
     *
     * @param geom1 an Expression representing a JGeometryObject
     * @param geom2 a JGeometryObject or an Expression representing a JGeometryObject
     * @param params a SpatialParameters object configured with the parameters to the call
     * @return a TopLink Expression
     */
    public static Expression filter(Expression geom1, Object geom2, SpatialParameters params) {
        String stringParameters = params == null ? null : params.getParameterString();
        return getSpatialExpression(SDO_FILTER, geom1, geom2, stringParameters);
    }

    /**
     * PUBLIC:
     * Return an Expression for the MDSYS.SDO_NN Spatial Operator on the Oracle Database
     * Use of this operator requires the Java spatial classes
     *
     * <blockquote><pre>
     * SpatialParameters parameters = new SpatialParameters();
     * parameters.setUnit(Units.M);
     * Expression selectCriteria = SpatialExpressions.nearestNeighbor(jGeometry1, jGeometry2, parameters);
     * </pre></blockquote>
     *
     * @param geom1 an Expression representing a JGeometryObject
     * @param geom2 a JGeometryObject or an Expression representing a JGeometryObject
     * @param params a SpatialParameters object configured with the parameters to the call
     * @return a TopLink Expression
     */
    public static Expression nearestNeighbor(Expression geom1, Object geom2, SpatialParameters params) {
        String stringParameters = params == null ? null : params.getParameterString();
        return getSpatialExpression(SDO_NN, geom1, geom2, stringParameters);
    }

    /**
     * INTERNAL:
     * A utility method to build a SpatialExpression
     *
     * @param operator the ordinal of the operator
     */
    public static Expression getSpatialExpression(int operator, Expression geom1, Object geom2, String params) {
        List<Object> vParameters = new Vector<>(2);
        vParameters.add(geom2);
        //Bug 5885276, the empty string either like " " or "" needs to be substituted
        //by null prior to passing to Geometry call.
        if (params==null || params.trim().equals("")){
            vParameters.add(null);
        }else{
            vParameters.add(params);
        }
        ExpressionOperator anOperator = geom1.getOperator(operator);
        FunctionExpression expression = new FunctionExpression();
        expression.create(geom1, vParameters, anOperator);
        Expression finalExpression = expression.equal("TRUE");
        return finalExpression;
    }
}
