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

import static org.apache.lucene.geo.XYEncodingUtils.decode;

import java.util.Arrays;
import java.util.function.Function;
import java.util.function.Predicate;
import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.XYEncodingUtils;
import org.apache.lucene.geo.XYGeometry;
import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.util.NumericUtils;

/**
 * Finds all previously indexed cartesian shapes that comply the given {@link QueryRelation} with
 * the specified array of {@link XYGeometry}.
 *
 * <p>The field must be indexed using {@link XYShape#createIndexableFields} added per document.
 */
final class XYShapeQuery extends SpatialQuery {
    final XYGeometry[] geometries;
    private final Component2D component2D;

    /** Creates a query that matches all indexed shapes to the provided polygons */
    XYShapeQuery(String field, QueryRelation queryRelation, XYGeometry... geometries) {
        super(field, queryRelation);
        this.component2D = XYGeometry.create(geometries);
        this.geometries = geometries.clone();
    }

    @Override
    protected SpatialVisitor getSpatialVisitor() {
        return new SpatialVisitor() {
            @Override
            protected Relation relate(byte[] minTriangle, byte[] maxTriangle) {

                double minY = XYEncodingUtils.decode(NumericUtils.sortableBytesToInt(minTriangle, 0));
                double minX =
                        XYEncodingUtils.decode(NumericUtils.sortableBytesToInt(minTriangle, ShapeField.BYTES));
                double maxY =
                        XYEncodingUtils.decode(
                                NumericUtils.sortableBytesToInt(maxTriangle, 2 * ShapeField.BYTES));
                double maxX =
                        XYEncodingUtils.decode(
                                NumericUtils.sortableBytesToInt(maxTriangle, 3 * ShapeField.BYTES));

                // check internal node against query
                return component2D.relate(minX, maxX, minY, maxY);
            }

            @Override
            protected Predicate<byte[]> intersects() {
                final ShapeField.DecodedTriangle scratchTriangle = new ShapeField.DecodedTriangle();
                return triangle -> {
                    ShapeField.decodeTriangle(triangle, scratchTriangle);

                    switch (scratchTriangle.type) {
                        case POINT:
                        {
                            double y = decode(scratchTriangle.aY);
                            double x = decode(scratchTriangle.aX);
                            return component2D.contains(x, y);
                        }
                        case LINE:
                        {
                            double aY = decode(scratchTriangle.aY);
                            double aX = decode(scratchTriangle.aX);
                            double bY = decode(scratchTriangle.bY);
                            double bX = decode(scratchTriangle.bX);
                            return component2D.intersectsLine(aX, aY, bX, bY);
                        }
                        case TRIANGLE:
                        {
                            double aY = decode(scratchTriangle.aY);
                            double aX = decode(scratchTriangle.aX);
                            double bY = decode(scratchTriangle.bY);
                            double bX = decode(scratchTriangle.bX);
                            double cY = decode(scratchTriangle.cY);
                            double cX = decode(scratchTriangle.cX);
                            return component2D.intersectsTriangle(aX, aY, bX, bY, cX, cY);
                        }
                        default:
                            throw new IllegalArgumentException(
                                    "Unsupported triangle type :[" + scratchTriangle.type + "]");
                    }
                };
            }

            @Override
            protected Predicate<byte[]> within() {
                final ShapeField.DecodedTriangle scratchTriangle = new ShapeField.DecodedTriangle();
                return triangle -> {
                    ShapeField.decodeTriangle(triangle, scratchTriangle);

                    switch (scratchTriangle.type) {
                        case POINT:
                        {
                            double y = decode(scratchTriangle.aY);
                            double x = decode(scratchTriangle.aX);
                            return component2D.contains(x, y);
                        }
                        case LINE:
                        {
                            double aY = decode(scratchTriangle.aY);
                            double aX = decode(scratchTriangle.aX);
                            double bY = decode(scratchTriangle.bY);
                            double bX = decode(scratchTriangle.bX);
                            return component2D.containsLine(aX, aY, bX, bY);
                        }
                        case TRIANGLE:
                        {
                            double aY = decode(scratchTriangle.aY);
                            double aX = decode(scratchTriangle.aX);
                            double bY = decode(scratchTriangle.bY);
                            double bX = decode(scratchTriangle.bX);
                            double cY = decode(scratchTriangle.cY);
                            double cX = decode(scratchTriangle.cX);
                            return component2D.containsTriangle(aX, aY, bX, bY, cX, cY);
                        }
                        default:
                            throw new IllegalArgumentException(
                                    "Unsupported triangle type :[" + scratchTriangle.type + "]");
                    }
                };
            }

            @Override
            protected Function<byte[], Component2D.WithinRelation> contains() {
                final ShapeField.DecodedTriangle scratchTriangle = new ShapeField.DecodedTriangle();
                return triangle -> {
                    ShapeField.decodeTriangle(triangle, scratchTriangle);

                    switch (scratchTriangle.type) {
                        case POINT:
                        {
                            double y = decode(scratchTriangle.aY);
                            double x = decode(scratchTriangle.aX);
                            return component2D.withinPoint(x, y);
                        }
                        case LINE:
                        {
                            double aY = decode(scratchTriangle.aY);
                            double aX = decode(scratchTriangle.aX);
                            double bY = decode(scratchTriangle.bY);
                            double bX = decode(scratchTriangle.bX);
                            return component2D.withinLine(aX, aY, scratchTriangle.ab, bX, bY);
                        }
                        case TRIANGLE:
                        {
                            double aY = decode(scratchTriangle.aY);
                            double aX = decode(scratchTriangle.aX);
                            double bY = decode(scratchTriangle.bY);
                            double bX = decode(scratchTriangle.bX);
                            double cY = decode(scratchTriangle.cY);
                            double cX = decode(scratchTriangle.cX);
                            return component2D.withinTriangle(
                                    aX,
                                    aY,
                                    scratchTriangle.ab,
                                    bX,
                                    bY,
                                    scratchTriangle.bc,
                                    cX,
                                    cY,
                                    scratchTriangle.ca);
                        }
                        default:
                            throw new IllegalArgumentException(
                                    "Unsupported triangle type :[" + scratchTriangle.type + "]");
                    }
                };
            }
        };
    }

    @Override
    public String toString(String field) {
        final StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(':');
        if (this.field.equals(field) == false) {
            sb.append(" field=");
            sb.append(this.field);
            sb.append(':');
        }
        sb.append("[");
        for (int i = 0; i < geometries.length; i++) {
            sb.append(geometries[i].toString());
            sb.append(',');
        }
        sb.append(']');
        return sb.toString();
    }

    @Override
    protected boolean equalsTo(Object o) {
        return super.equalsTo(o) && Arrays.equals(geometries, ((XYShapeQuery) o).geometries);
    }

    @Override
    public int hashCode() {
        int hash = super.hashCode();
        hash = 31 * hash + Arrays.hashCode(geometries);
        return hash;
    }
}
