// Path: src/main/java/com/indoqa/solr/spatial/corridor/LineStringUtils.java
// public final class LineStringUtils {
// 
//     static {
//         cache = Caffeine.newBuilder()
//                 .maximumSize(100000)
//                 .expireAfterAccess(24, TimeUnit.HOURS)
//                 .build();
//     }
// 
//     private static Cache<String, LineString> cache;
// 
//     public static LineString parseOrGet(String value, String hash)  {
//         if (value == null) {
//             return null;
//         }
// 
//         if (hash != null) {
//             LineString cached = cache.getIfPresent(hash);
// 
//             if (cached != null) {
//                 return cached;
//             }
//         }
// 
//         String key = calculateHash(value);
//         return cache.get(key, s -> parseWktLinestring(value));
//     }
// 
//     public static HashGeometry cacheLineStringGetHashGeometry(String linestring, int radiusInMeters){
//         if(linestring == null){
//             return null;
//         }
//         String key = calculateHash(linestring);
//         LineString parsedLineString = parseWktLinestring(linestring);
// 
//         cache.put(key, parsedLineString);
//         HashGeometry result = new HashGeometry();
//         // meters /((PI/180)x6378137)
//         result.setGeometry(parsedLineString.buffer(radiusInMeters / (Math.PI / 180 * 6378137)).toText());
//         result.setHash(key);
//         return result;
//     }
// 
//     public static void purgeCache() {
//         cache.invalidateAll();
//         cache.cleanUp();
//     }
// 
//     private static LineString parseWktLinestring(String corridorLineString) {
//         return WktUtils.parseLineString(corridorLineString);
//     }
// 
//     private static String calculateHash(String linestring) {
//         if (linestring == null) {
//             return null;
//         }
// 
//         StringBuilder result = new StringBuilder("hash-");
//         result.append(Hex.encodeHex(DigestUtils.md5(linestring)));
//         return result.toString();
//     }
// }


import com.indoqa.solr.spatial.corridor.LineStringUtils;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.search.Query;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.FunctionRangeQuery;
import org.apache.solr.search.QParser;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.search.function.ValueSourceRangeFilter;
import org.locationtech.jts.geom.LineString;
/*
 * Licensed to the Indoqa Software Design und Beratung GmbH (Indoqa) under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Indoqa 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 com.indoqa.solr.spatial.corridor.query.route;



public class RouteQueryParser extends QParser {

    public RouteQueryParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
        super(qstr, localParams, params, req);
    }

    @Override
    public Query parse() throws SyntaxError {
        ValueSource locationValueSource = this.parseLocationValueSource();

        LineString lineString = this.parseLineString();
        String buffer = this.parseBuffer();

        RouteDistanceValueSource corridorDistanceValueSource = new RouteDistanceValueSource(lineString, locationValueSource);
        ValueSourceRangeFilter filter = new ValueSourceRangeFilter(corridorDistanceValueSource, "0", buffer, true, true);
        return new FunctionRangeQuery(filter);
    }

    private String parseBuffer() {
        String buffer = this.getParam("buffer");

        if (buffer == null) {
            return "5";
        }

        return buffer;
    }

    private LineString parseLineString() throws SyntaxError {
// Path: src/main/java/com/indoqa/solr/spatial/corridor/LineStringUtils.java
// public final class LineStringUtils {
// 
//     static {
//         cache = Caffeine.newBuilder()
//                 .maximumSize(100000)
//                 .expireAfterAccess(24, TimeUnit.HOURS)
//                 .build();
//     }
// 
//     private static Cache<String, LineString> cache;
// 
//     public static LineString parseOrGet(String value, String hash)  {
//         if (value == null) {
//             return null;
//         }
// 
//         if (hash != null) {
//             LineString cached = cache.getIfPresent(hash);
// 
//             if (cached != null) {
//                 return cached;
//             }
//         }
// 
//         String key = calculateHash(value);
//         return cache.get(key, s -> parseWktLinestring(value));
//     }
// 
//     public static HashGeometry cacheLineStringGetHashGeometry(String linestring, int radiusInMeters){
//         if(linestring == null){
//             return null;
//         }
//         String key = calculateHash(linestring);
//         LineString parsedLineString = parseWktLinestring(linestring);
// 
//         cache.put(key, parsedLineString);
//         HashGeometry result = new HashGeometry();
//         // meters /((PI/180)x6378137)
//         result.setGeometry(parsedLineString.buffer(radiusInMeters / (Math.PI / 180 * 6378137)).toText());
//         result.setHash(key);
//         return result;
//     }
// 
//     public static void purgeCache() {
//         cache.invalidateAll();
//         cache.cleanUp();
//     }
// 
//     private static LineString parseWktLinestring(String corridorLineString) {
//         return WktUtils.parseLineString(corridorLineString);
//     }
// 
//     private static String calculateHash(String linestring) {
//         if (linestring == null) {
//             return null;
//         }
// 
//         StringBuilder result = new StringBuilder("hash-");
//         result.append(Hex.encodeHex(DigestUtils.md5(linestring)));
//         return result.toString();
//     }
// }


// Path: src/main/java/com/indoqa/solr/spatial/corridor/query/route/RouteQueryParser.java
import com.indoqa.solr.spatial.corridor.LineStringUtils;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.search.Query;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.FunctionRangeQuery;
import org.apache.solr.search.QParser;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.search.function.ValueSourceRangeFilter;
import org.locationtech.jts.geom.LineString;

/*
 * Licensed to the Indoqa Software Design und Beratung GmbH (Indoqa) under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Indoqa 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 com.indoqa.solr.spatial.corridor.query.route;



public class RouteQueryParser extends QParser {

    public RouteQueryParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
        super(qstr, localParams, params, req);
    }

    @Override
    public Query parse() throws SyntaxError {
        ValueSource locationValueSource = this.parseLocationValueSource();

        LineString lineString = this.parseLineString();
        String buffer = this.parseBuffer();

        RouteDistanceValueSource corridorDistanceValueSource = new RouteDistanceValueSource(lineString, locationValueSource);
        ValueSourceRangeFilter filter = new ValueSourceRangeFilter(corridorDistanceValueSource, "0", buffer, true, true);
        return new FunctionRangeQuery(filter);
    }

    private String parseBuffer() {
        String buffer = this.getParam("buffer");

        if (buffer == null) {
            return "5";
        }

        return buffer;
    }

    private LineString parseLineString() throws SyntaxError {
        return LineStringUtils.parseOrGet(this.getParam("corridor.route"), null);