# AttrComparator.java

    package io.github.js0ny.ilp_coursework.util;

    import com.fasterxml.jackson.databind.JsonNode;

    import java.math.BigDecimal;

    /**
     * Comparator for attribute values in {@code JsonNode}.
     *
     * <p>This is a helper for dynamic querying.
     */
    public class AttrComparator {
        /**
         * Helper for dynamic querying, to compare the json value with given value in {@code String}.
         *
         * @param node The {@code JsonNode} to be compared
         * @param attrVal The Value passed, in {@code String}
         * @param op The comparison operator
         * @return {@code true} if given values are equal, otherwise false.
         */
        public static boolean isValueMatched(JsonNode node, String attrVal, AttrOperator op) {
            if (node.isTextual()) {
                return compareStrings(node.asText(), attrVal, op);
            } else if (node.isNumber()) {
                // return Double.compare(node.asDouble(), Double.parseDouble(attrVal)) == 0;
                return compareNumbers(node.decimalValue(), new BigDecimal(attrVal), op);
            } else if (node.isBoolean()) {
                return compareBooleans(node.asBoolean(), Boolean.parseBoolean(attrVal), op);
            } else {
                return false;
            }
        }

        private static boolean compareNumbers(BigDecimal nodeVal, BigDecimal attrVal, AttrOperator op) {
            int comparison = nodeVal.compareTo(attrVal);
            return switch (op) {
                case EQ -> comparison == 0;
                case GT -> comparison > 0;
                case LT -> comparison < 0;
                case NE -> comparison != 0;
            };
        }

        private static boolean compareStrings(String nodeVal, String attrVal, AttrOperator op) {
            return switch (op) {
                case EQ -> nodeVal.equals(attrVal);
                default -> !nodeVal.equals(attrVal);
                    // case NE -> !nodeVal.equals(attrVal);
                    // case GT -> !nodeVal.equals(attrVal);// > 0;
                    // case LT -> !nodeVal.equals(attrVal);// < 0;
            };
        }

        private static boolean compareBooleans(boolean nodeVal, boolean attrVal, AttrOperator op) {
            return switch (op) {
                case EQ -> nodeVal == attrVal;
                default -> nodeVal != attrVal;
                    // case NE -> nodeVal != attrVal;
                    // case GT -> !nodeVal && attrVal; // false < true
                    // case LT -> nodeVal && !attrVal; // true > false
            };
        }
    }