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

import org.apache.johnzon.jsonlogic.spi.Operator;

import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonBuilderFactory;
import javax.json.JsonException;
import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonPointer;
import javax.json.JsonString;
import javax.json.JsonStructure;
import javax.json.JsonValue;
import javax.json.spi.JsonProvider;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.BiPredicate;
import java.util.stream.Collector;
import java.util.stream.DoubleStream;
import java.util.stream.Stream;

import static java.util.Collections.emptyMap;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static java.util.stream.Collectors.joining;

public class JohnzonJsonLogic {
    private final JsonProvider provider;
    private final Map<String, Operator> operators = new HashMap<>();
    private final Map<String, JsonPointer> pointers = new HashMap<>();
    private final JsonBuilderFactory builderFactory;
    private boolean cachePointers;

    public JohnzonJsonLogic() {
        this(JsonProvider.provider());
        registerDefaultOperators();
    }

    public JohnzonJsonLogic(final JsonProvider provider) {
        this.provider = provider;
        this.builderFactory = provider.createBuilderFactory(emptyMap());
    }

    public JohnzonJsonLogic cachePointers() {
        this.cachePointers = true;
        return this;
    }

    public JohnzonJsonLogic registerOperator(final String name, final Operator impl) {
        operators.put(name, impl);
        return this;
    }

    public JsonValue apply(final JsonValue logic, final JsonValue args) {
        if (logic.getValueType() != JsonValue.ValueType.OBJECT) {
            return logic;
        }

        final JsonObject object = logic.asJsonObject();
        if (object.size() > 1) {
            return object;
        }

        final Set<String> keys = object.keySet();
        if (keys.size() != 1) {
            throw invalidArgument(keys);
        }
        final String operator = keys.iterator().next();
        final Operator impl = operators.get(operator);
        if (impl == null) {
            throw missingOperator(operator);
        }
        return impl.apply(this, object.get(operator), args);
    }

    public CompletionStage<JsonValue> applyStage(final JsonValue logic, final JsonValue args) {
        if (logic.getValueType() != JsonValue.ValueType.OBJECT) {
            return completedFuture(logic);
        }

        final JsonObject object = logic.asJsonObject();
        if (object.size() > 1) {
            return completedFuture(object);
        }

        final Set<String> keys = object.keySet();
        if (keys.size() != 1) {
            final CompletableFuture<JsonValue> promise = new CompletableFuture<>();
            promise.completeExceptionally(invalidArgument(keys));
            return promise;
        }
        final String operator = keys.iterator().next();
        final Operator impl = operators.get(operator);
        if (impl == null) {
            final CompletableFuture<JsonValue> promise = new CompletableFuture<>();
            promise.completeExceptionally(missingOperator(operator));
            return promise;
        }
        return impl.applyStage(this, object.get(operator), args);
    }

    public boolean isTruthy(final JsonValue value) {
        return !isFalsy(value);
    }

    public boolean isFalsy(final JsonValue value) {
        switch (value.getValueType()) {
            case NUMBER:
                return JsonNumber.class.cast(value).intValue() == 0;
            case ARRAY:
                return value.asJsonArray().isEmpty();
            case STRING:
                return JsonString.class.cast(value).getString().isEmpty();
            case FALSE:
            case NULL:
                return true;
            default:
                return false;
        }
    }

    public boolean areEqualsWithCoercion(final JsonValue a, final JsonValue b) {
        if (a == b) {
            return true;
        }
        if (a == null) {
            return false;
        }
        if (b == null) {
            return false;
        }
        if (a.getValueType() == b.getValueType()) {
            return a.equals(b);
        }
        switch (a.getValueType()) {
            case STRING:
                switch (b.getValueType()) {
                    case NUMBER:
                        try {
                            return Double.parseDouble(JsonString.class.cast(a).getString()) == JsonNumber.class.cast(b).doubleValue();
                        } catch (final NumberFormatException nfe) {
                            return false;
                        }
                    case TRUE:
                    case FALSE:
                        return isFalsy(a) == isFalsy(b);
                    default:
                        return false;
                }
            case NUMBER:
                switch (b.getValueType()) {
                    case STRING:
                        try {
                            return Double.parseDouble(JsonString.class.cast(b).getString()) == JsonNumber.class.cast(a).doubleValue();
                        } catch (final NumberFormatException nfe) {
                            return false;
                        }
                    case TRUE:
                    case FALSE:
                    default:
                        return isFalsy(a) == isFalsy(b);
                }
            case TRUE:
            case FALSE:
                return isFalsy(a) == isFalsy(b);
            default:
                return false;
        }
    }

    // to not depend on a logger we don't register "log" operation but it is trivial to do:
    public JohnzonJsonLogic registerDefaultOperators() {
        registerOperator("log", (logic, config, params) -> {
            throw new UnsupportedOperationException("Log is not supported by default, register the following operator with your preferred logger:\n\n" +
                    "jsonLogic.registerOperator(\"log\", (l, c, p) -> log.info(String.valueOf(l.apply(c, p)));\n");
        });
        registerOperator("var", (logic, config, params) -> varImpl(config, params));
        registerOperator("missing", this::missingImpl);
        registerOperator("missing_some", this::missingSomeImpl);
        registerOperator("if", this::ifImpl);
        registerOperator("<", (logic, config, params) -> numericComparison((a, b) -> a < b, config, logic, params));
        registerOperator(">", (logic, config, params) -> numericComparison((a, b) -> a > b, config, logic, params));
        registerOperator("<=", (logic, config, params) -> numericComparison((a, b) -> a <= b, config, logic, params));
        registerOperator(">=", (logic, config, params) -> numericComparison((a, b) -> a >= b, config, logic, params));
        registerOperator("==", (logic, config, params) -> comparison(this::areEqualsWithCoercion, config, logic, params));
        registerOperator("!=", (logic, config, params) -> comparison((a, b) -> !areEqualsWithCoercion(a, b), config, logic, params));
        registerOperator("===", (logic, config, params) -> comparison(Objects::equals, config, logic, params));
        registerOperator("!==", (logic, config, params) -> comparison((a, b) -> !Objects.equals(a, b), config, logic, params));
        registerOperator("!", this::notImpl);
        registerOperator("!!", this::toBooleanImpl);
        registerOperator("or", this::orImpl);
        registerOperator("and", this::andImpl);
        registerOperator("min", this::minImpl);
        registerOperator("max", this::maxImpl);
        registerOperator("+", this::plusImpl);
        registerOperator("*", this::multiplyImpl);
        registerOperator("-", this::minusImpl);
        registerOperator("/", this::divideImpl);
        registerOperator("%", this::moduloImpl);
        registerOperator("map", this::mapImpl);
        registerOperator("filter", this::filterImpl);
        registerOperator("reduce", this::reduceImpl);
        registerOperator("all", (logic, config, params) ->
                arrayTest(logic, config, params, (subConf, stream) -> stream.allMatch(it -> isTruthy(logic.apply(subConf, it)))));
        registerOperator("some", (logic, config, params) ->
                arrayTest(logic, config, params, (subConf, stream) -> stream.anyMatch(it -> isTruthy(logic.apply(subConf, it)))));
        registerOperator("none", (logic, config, params) ->
                arrayTest(logic, config, params, (subConf, stream) -> stream.noneMatch(it -> isTruthy(logic.apply(subConf, it)))));
        registerOperator("merge", (logic, config, params) -> mergeImpl(config));
        registerOperator("in", this::inImpl);
        registerOperator("cat", this::catImpl);
        registerOperator("substr", this::substrImpl);
        return this;
    }

    private IllegalArgumentException invalidArgument(final Set<String> keys) {
        return new IllegalArgumentException("Invalid argument, multiple keys found: " + keys);
    }

    private IllegalArgumentException missingOperator(final String operator) {
        return new IllegalArgumentException("Missing operator '" + operator + "'");
    }

    private JsonValue minImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("min only supports arrays: '" + config + "'");
        }
        return provider.createValue(mapToDouble(logic, config, params).min().orElse(0));
    }

    private JsonValue maxImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("max only supports arrays: '" + config + "'");
        }
        return provider.createValue(mapToDouble(logic, config, params).max().orElse(0));
    }

    private JsonValue plusImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            return castToNumber(logic.apply(config, params));
        }
        if (config.asJsonArray().isEmpty()) {
            return provider.createValue(0);
        }
        return provider.createValue(mapToDouble(logic, config, params).sum());
    }

    private JsonValue multiplyImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("* only supports arrays: '" + config + "'");
        }
        if (config.asJsonArray().isEmpty()) {
            return provider.createValue(0);
        }
        return provider.createValue(mapToDouble(logic, config, params)
                .reduce(1, (a, b) -> a * b));
    }

    private JsonValue minusImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() != 2) {
                throw new IllegalArgumentException("- only supports arrays with 2 elements: '" + config + "'");
            }
            return provider.createValue(JsonNumber.class.cast(logic.apply(array.get(0), params)).doubleValue() -
                    JsonNumber.class.cast(logic.apply(array.get(1), params)).doubleValue());
        }
        final JsonValue applied = logic.apply(config, params);
        if (applied.getValueType() == JsonValue.ValueType.NUMBER) {
            return provider.createValue(-1 * JsonNumber.class.cast(applied).doubleValue());
        }
        throw new IllegalArgumentException("Unsupported - operation: '" + config + "'");
    }

    private JsonValue divideImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() != 2) {
                throw new IllegalArgumentException("/ only supports arrays with 2 elements: '" + config + "'");
            }
            return provider.createValue(JsonNumber.class.cast(logic.apply(array.get(0), params)).doubleValue() /
                    JsonNumber.class.cast(logic.apply(array.get(1), params)).doubleValue());
        }
        throw new IllegalArgumentException("Unsupported / operation: '" + config + "'");
    }

    private JsonValue moduloImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() != 2) {
                throw new IllegalArgumentException("% only supports arrays with 2 elements: '" + config + "'");
            }
            return provider.createValue(JsonNumber.class.cast(logic.apply(array.get(0), params)).doubleValue() %
                    JsonNumber.class.cast(logic.apply(array.get(1), params)).doubleValue());
        }
        throw new IllegalArgumentException("Unsupported % operation: '" + config + "'");
    }

    private JsonValue mapImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() != 2) {
                throw new IllegalArgumentException("map only supports arrays with 2 elements: '" + config + "'");
            }
            final JsonValue items = logic.apply(array.get(0), params);
            if (items.getValueType() != JsonValue.ValueType.ARRAY) {
                throw new IllegalArgumentException("Expected '" + array.get(0) + "' to be an array, got " + items.getValueType());
            }
            final JsonValue subLogic = array.get(1);
            return items.asJsonArray().stream()
                    .map(it -> logic.apply(subLogic, it))
                    .collect(toArray());
        }
        throw new IllegalArgumentException("Unsupported map operation: '" + config + "'");
    }

    private JsonValue filterImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() != 2) {
                throw new IllegalArgumentException("filter only supports arrays with 2 elements: '" + config + "'");
            }
            final JsonValue items = logic.apply(array.get(0), params);
            if (items.getValueType() != JsonValue.ValueType.ARRAY) {
                throw new IllegalArgumentException("Expected '" + array.get(0) + "' to be an array, got " + items.getValueType());
            }
            final JsonValue subLogic = array.get(1);
            return items.asJsonArray().stream()
                    .filter(it -> isTruthy(logic.apply(subLogic, it)))
                    .collect(toArray());
        }
        throw new IllegalArgumentException("Unsupported filter operation: '" + config + "'");
    }

    private JsonValue mergeImpl(final JsonValue config) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("merge only support an array as configuration, got '" + config + "'");
        }
        return config.asJsonArray().stream()
                .flatMap(it -> it.getValueType() == JsonValue.ValueType.ARRAY ?
                        it.asJsonArray().stream() : builderFactory.createArrayBuilder().add(it).build().stream())
                .collect(toArray());
    }

    private JsonValue substrImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY || config.asJsonArray().size() < 2) {
            throw new IllegalArgumentException("substr only support an array as configuration, got '" + config + "'");
        }
        final JsonArray array = config.asJsonArray();
        final JsonValue value = logic.apply(array.get(0), params);
        if (value.getValueType() != JsonValue.ValueType.STRING) {
            throw new IllegalArgumentException("expected a string for substr, got '" + value + "'");
        }
        final String valueStr = JsonString.class.cast(value).getString();
        final JsonValue from = logic.apply(array.get(1), params);
        if (from.getValueType() != JsonValue.ValueType.NUMBER) {
            throw new IllegalArgumentException("expected a number for substr, got '" + from + "'");
        }
        final int fromIdx = JsonNumber.class.cast(from).intValue();
        final int start;
        if (fromIdx < 0) {
            start = valueStr.length() + fromIdx;
        } else {
            start = fromIdx;
        }
        final int end;
        if (array.size() == 3) {
            final JsonValue to = logic.apply(array.get(2), params);
            if (to.getValueType() != JsonValue.ValueType.NUMBER) {
                throw new IllegalArgumentException("expected a number for substr, got '" + to + "'");
            }
            final int length = JsonNumber.class.cast(to).intValue();
            end = length < 0 ? valueStr.length() + length : start + length;
        } else {
            end = valueStr.length();
        }
        return provider.createValue(valueStr.substring(start, end));
    }

    private JsonValue catImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("cat only support an array of string elements as configuration, got '" + config + "'");
        }
        return provider.createValue(config.asJsonArray().stream()
                .map(it -> logic.apply(it, params))
                .filter(it -> it.getValueType() == JsonValue.ValueType.STRING)
                .map(it -> JsonString.class.cast(it).getString())
                .collect(joining()));
    }

    private JsonValue inImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY || config.asJsonArray().size() != 2) {
            throw new IllegalArgumentException("in only support an array of 2 elements as configuration, got '" + config + "'");
        }
        final JsonArray array = config.asJsonArray();
        final JsonValue expected = logic.apply(array.get(0), params);
        final JsonValue value = logic.apply(array.get(1), params);
        switch (value.getValueType()) {
            case STRING:
                return expected.getValueType() == JsonValue.ValueType.STRING && JsonString.class.cast(value).getString()
                        .contains(JsonString.class.cast(expected).getString()) ? JsonValue.TRUE : JsonValue.FALSE;
            case ARRAY:
                return value.getValueType() == JsonValue.ValueType.ARRAY && value.asJsonArray().stream()
                        .anyMatch(it -> Objects.equals(it, expected)) ? JsonValue.TRUE : JsonValue.FALSE;
            default:
                return JsonValue.FALSE;
        }
    }

    private JsonValue reduceImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() < 2 || array.size() > 3) {
                throw new IllegalArgumentException("filter only supports arrays with 2 or 3 elements: '" + config + "'");
            }
            final JsonValue items = logic.apply(array.get(0), params);
            if (items.getValueType() != JsonValue.ValueType.ARRAY) {
                throw new IllegalArgumentException("Expected '" + array.get(0) + "' to be an array, got " + items.getValueType());
            }
            final JsonValue subLogic = array.get(1);
            return items.asJsonArray().stream()
                    .reduce(
                            array.size() == 3 ? array.get(2) : JsonValue.NULL,
                            (accumulator, current) -> logic.apply(subLogic, builderFactory.createObjectBuilder()
                                    .add("accumulator", accumulator)
                                    .add("current", current)
                                    .build()));
        }
        throw new IllegalArgumentException("Unsupported reduce operation: '" + config + "'");
    }

    private JsonValue andImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("and only supports arrays: '" + config + "'");
        }
        final JsonArray array = config.asJsonArray();
        return array.stream()
                .map(it -> logic.apply(it, params))
                .filter(this::isFalsy)
                .findFirst()
                .orElseGet(() -> array.isEmpty() ? JsonValue.FALSE : array.get(array.size() - 1));
    }

    private JsonValue orImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("or only supports arrays: '" + config + "'");
        }
        final JsonArray array = config.asJsonArray();
        return array.stream()
                .map(it -> logic.apply(it, params))
                .filter(this::isTruthy)
                .findFirst()
                .orElseGet(() -> array.isEmpty() ? JsonValue.FALSE : array.get(array.size() - 1));
    }

    private JsonValue toBooleanImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() != 1) {
                throw new IllegalArgumentException("!! takes only one parameter '" + config + "'");
            }
            return isTruthy(logic.apply(array.get(0), params)) ? JsonValue.TRUE : JsonValue.FALSE;
        }
        return isTruthy(logic.apply(config, params)) ? JsonValue.TRUE : JsonValue.FALSE;
    }

    private JsonValue notImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() != 1) {
                throw new IllegalArgumentException("! takes only one parameter '" + config + "'");
            }
            return isFalsy(logic.apply(array.get(0), params)) ? JsonValue.TRUE : JsonValue.FALSE;
        }
        return isFalsy(logic.apply(config, params)) ? JsonValue.TRUE : JsonValue.FALSE;
    }

    private JsonValue ifImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("if config must be an array");
        }
        final JsonArray configArray = config.asJsonArray();
        if (configArray.size() < 2) {
            throw new IllegalArgumentException("if config must be an array >= 2 elements");
        }
        for (int i = 0; i < configArray.size() - 1; i += 2) {
            if (isTruthy(logic.apply(configArray.get(i), params))) {
                return logic.apply(configArray.get(i + 1), params);
            }
        }
        if (configArray.size() % 2 == 1) {
            return configArray.get(configArray.size() - 1);
        }
        return JsonValue.FALSE;
    }

    private JsonValue missingSomeImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("missing_some takes an array as parameter: '" + config + "'");
        }
        final JsonArray configArray = config.asJsonArray();
        if (configArray.size() != 2) {
            throw new IllegalArgumentException("missing_some takes an array with a number and a path array as parameter: '" + config + "'");
        }
        final JsonArray tested = configArray.get(1).asJsonArray();
        final JsonArray missing = tested.stream()
                .filter(it -> varImpl(logic.apply(it, params), params) == JsonValue.NULL)
                .collect(toArray());
        if ((tested.size() - missing.size()) < JsonNumber.class.cast(logic.apply(configArray.get(0), params)).intValue()) {
            return missing;
        }
        return JsonValue.EMPTY_JSON_ARRAY;
    }

    private JsonValue missingImpl(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("missing takes an array as parameter: '" + config + "'");
        }
        return config.asJsonArray().stream()
                .filter(it -> varImpl(logic.apply(it, params), params) == JsonValue.NULL)
                .collect(toArray());
    }

    private JsonValue arrayTest(final JohnzonJsonLogic self, final JsonValue config, final JsonValue params,
                                final BiPredicate<JsonValue, Stream<JsonValue>> tester) {
        if (config.getValueType() == JsonValue.ValueType.ARRAY) {
            final JsonArray array = config.asJsonArray();
            if (array.size() != 2) {
                throw new IllegalArgumentException("array test only supports arrays with 2: '" + config + "'");
            }
            final JsonValue items = self.apply(array.get(0), params);
            if (items.getValueType() != JsonValue.ValueType.ARRAY) {
                throw new IllegalArgumentException("Expected '" + array.get(0) + "' to be an array, got " + items.getValueType());
            }
            final JsonValue subLogic = array.get(1);
            return tester.test(subLogic, items.asJsonArray().stream()) ? JsonValue.TRUE : JsonValue.FALSE;
        }
        throw new IllegalArgumentException("Unsupported array test operation: '" + config + "'");
    }

    private JsonValue castToNumber(final JsonValue value) {
        switch (value.getValueType()) {
            case NUMBER:
                return value;
            case STRING:
                return provider.createValue(Double.parseDouble(JsonString.class.cast(value).getString()));
            default:
                throw new IllegalArgumentException("Unsupported value to number: '" + value + "'");
        }
    }

    private DoubleStream mapToDouble(final JohnzonJsonLogic logic, final JsonValue config, final JsonValue params) {
        return config.asJsonArray().stream()
                .map(it -> logic.apply(it, params))
                .filter(it -> it.getValueType() == JsonValue.ValueType.NUMBER)
                .mapToDouble(it -> JsonNumber.class.cast(it).doubleValue());
    }

    private JsonValue comparison(final BiPredicate<JsonValue, JsonValue> comparator,
                                 final JsonValue config, final JohnzonJsonLogic self,
                                 final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("comparison config must be an array");
        }
        final JsonArray values = config.asJsonArray();
        if (values.size() != 2) {
            throw new IllegalArgumentException("comparison requires 2 arguments");
        }
        final JsonValue first = self.apply(values.get(0), params);
        final JsonValue second = self.apply(values.get(1), params);
        return comparator.test(first, second) ? JsonValue.TRUE : JsonValue.FALSE;
    }

    private JsonValue numericComparison(final BiPredicate<Double, Double> comparator,
                                        final JsonValue config, final JohnzonJsonLogic self,
                                        final JsonValue params) {
        if (config.getValueType() != JsonValue.ValueType.ARRAY) {
            throw new IllegalArgumentException("numeric comparison config must be an array");
        }
        final JsonArray configArray = config.asJsonArray();
        switch (configArray.size()) {
            case 2: {
                final JsonValue first = self.apply(configArray.get(0), params);
                final JsonValue second = self.apply(configArray.get(1), params);
                if (Stream.of(first, second).anyMatch(it -> it.getValueType() != JsonValue.ValueType.NUMBER)) {
                    throw new IllegalArgumentException("Only numbers can be compared: " + first + " / " + second);
                }
                return comparator.test(JsonNumber.class.cast(first).doubleValue(), JsonNumber.class.cast(second).doubleValue()) ?
                        JsonValue.TRUE : JsonValue.FALSE;
            }
            case 3: { // between
                final JsonValue first = self.apply(configArray.get(0), params);
                final JsonValue second = self.apply(configArray.get(1), params);
                final JsonValue third = self.apply(configArray.get(1), params);
                if (Stream.of(first, second, third).anyMatch(it -> it.getValueType() != JsonValue.ValueType.NUMBER)) {
                    throw new IllegalArgumentException("Only numbers can be compared");
                }
                return comparator.test(JsonNumber.class.cast(first).doubleValue(), JsonNumber.class.cast(second).doubleValue()) &&
                        comparator.test(JsonNumber.class.cast(second).doubleValue(), JsonNumber.class.cast(third).doubleValue()) ?
                        JsonValue.TRUE : JsonValue.FALSE;
            }
            default:
                throw new IllegalArgumentException("numeric comparison config must be an array >= 2 elements");
        }
    }

    private JsonValue varImpl(final JsonValue config, final JsonValue params) {
        switch (config.getValueType()) {
            case ARRAY:
                final JsonArray values = config.asJsonArray();
                if (values.isEmpty()) {
                    throw new IllegalArgumentException("var should have at least one parameter");
                }
                final JsonValue accessor = apply(values.get(0), params);
                switch (accessor.getValueType()) {
                    case NUMBER:
                        final int index = JsonNumber.class.cast(accessor).intValue();
                        final JsonArray array = params.asJsonArray();
                        final JsonValue arrayAttribute = index >= array.size() ? null : array.get(index);
                        return arrayAttribute == null ? (values.size() > 1 ? apply(values.get(1), params) : JsonValue.NULL) : arrayAttribute;
                    case STRING:
                        final JsonValue objectAttribute = extractValue(params, JsonString.class.cast(accessor).getString());
                        return objectAttribute == JsonValue.NULL && values.size() > 1 ? apply(values.get(1), params) : objectAttribute;
                    default:
                        throw new IllegalArgumentException("Unsupported var first paraemter: '" + accessor + "', should be string or number");
                }
            case STRING:
                return extractValue(params, JsonString.class.cast(config).getString());
            case NUMBER:
                final int index = JsonNumber.class.cast(config).intValue();
                final JsonArray array = params.asJsonArray();
                final JsonValue arrayAttribute = array.size() <= index ? null : array.get(index);
                return arrayAttribute == null ? JsonValue.NULL : arrayAttribute;
            case OBJECT:
                return varImpl(apply(config, params), params);
            default:
                throw new IllegalArgumentException("Unsupported configuration for var: '" + config + "'");
        }
    }

    private JsonValue extractValue(final JsonValue params, final String string) {
        if (string.isEmpty()) {
            return params;
        }
        final JsonValue objectAttribute;
        if (string.contains(".")) {
            try {
                objectAttribute = toPointer(string).getValue(JsonStructure.class.cast(params));
            } catch (final JsonException je) { // missing
                return JsonValue.NULL;
            }
        } else if (params.getValueType() == JsonValue.ValueType.OBJECT) {
            objectAttribute = params.asJsonObject().get(string);
        } else if (params.getValueType() == JsonValue.ValueType.ARRAY) {
            objectAttribute = params.asJsonArray().get(Integer.parseInt(string.trim()));
        } else {
            objectAttribute = null;
        }
        return objectAttribute == null ? JsonValue.NULL : objectAttribute;
    }

    // cache?
    private JsonPointer toPointer(final String string) {
        if (cachePointers) {
            return pointers.computeIfAbsent(string, this::doToPointer);
        }
        return doToPointer(string);
    }

    private JsonPointer doToPointer(final String string) {
        return provider.createPointer(
                (!string.startsWith("/") ? "/" : "") +
                        string.replace('.', '/'));
    }

    // same as JsonCollector one except it uses this builderFactory instead of default one which goes through the SPI
    private Collector<JsonValue, JsonArrayBuilder, JsonArray> toArray() {
        return Collector.of(builderFactory::createArrayBuilder, JsonArrayBuilder::add, JsonArrayBuilder::addAll, JsonArrayBuilder::build);
    }
}
