/*
 * 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.unomi.plugins.baseplugin.conditions;

import ognl.*;
import ognl.enhance.ExpressionAccessor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.unomi.api.*;
import org.apache.unomi.api.conditions.Condition;
import org.apache.unomi.api.rules.Rule;
import org.apache.unomi.scripting.ExpressionFilter;
import org.apache.unomi.scripting.ExpressionFilterFactory;
import org.apache.unomi.scripting.SecureFilteringClassLoader;
import org.apache.unomi.persistence.elasticsearch.conditions.ConditionContextHelper;
import org.apache.unomi.persistence.elasticsearch.conditions.ConditionEvaluator;
import org.apache.unomi.persistence.elasticsearch.conditions.ConditionEvaluatorDispatcher;
import org.apache.unomi.persistence.spi.PropertyHelper;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.joda.JodaDateMathParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Evaluator for property comparison conditions
 */
public class PropertyConditionEvaluator implements ConditionEvaluator {

    private static final Logger logger = LoggerFactory.getLogger(PropertyConditionEvaluator.class.getName());

    private static final SimpleDateFormat yearMonthDayDateFormat = new SimpleDateFormat("yyyyMMdd");
    public static final String NOT_OPTIMIZED_MARKER = "$$$###NOT_OPTIMIZED###$$$";

    private Map<String, Map<String, ExpressionAccessor>> expressionCache = new HashMap<>(64);
    private boolean usePropertyConditionOptimizations = true;
    private static ClassLoader secureFilteringClassLoader = new SecureFilteringClassLoader(PropertyConditionEvaluator.class.getClassLoader());
    private ExpressionFilterFactory expressionFilterFactory;

    private boolean useOGNLScripting = Boolean.parseBoolean(System.getProperty("org.apache.unomi.security.properties.useOGNLScripting", "false"));

    public void setUsePropertyConditionOptimizations(boolean usePropertyConditionOptimizations) {
        this.usePropertyConditionOptimizations = usePropertyConditionOptimizations;
    }

    public void setExpressionFilterFactory(ExpressionFilterFactory expressionFilterFactory) {
        this.expressionFilterFactory = expressionFilterFactory;
    }

    private int compare(Object actualValue, String expectedValue, Object expectedValueDate, Object expectedValueInteger, Object expectedValueDateExpr, Object expectedValueDouble) {
        if (expectedValue == null && expectedValueDate == null && expectedValueInteger == null && getDate(expectedValueDateExpr) == null) {
            return actualValue == null ? 0 : 1;
        } else if (actualValue == null) {
            return -1;
        }

        if (expectedValueInteger != null) {
            return PropertyHelper.getInteger(actualValue).compareTo(PropertyHelper.getInteger(expectedValueInteger));
        } else if (expectedValueDouble != null) {
            return PropertyHelper.getDouble(actualValue).compareTo(PropertyHelper.getDouble(expectedValueDouble));
        } else if (expectedValueDate != null) {
            return getDate(actualValue).compareTo(getDate(expectedValueDate));
        } else if (expectedValueDateExpr != null) {
            return getDate(actualValue).compareTo(getDate(expectedValueDateExpr));
        } else {
            return actualValue.toString().compareTo(expectedValue);
        }
    }

    private boolean compareMultivalue(Object actualValue, List<?> expectedValues, List<?> expectedValuesDate, List<?> expectedValuesNumber, List<?> expectedValuesDateExpr, String op) {
        @SuppressWarnings("unchecked")
        List<?> expected = ObjectUtils.firstNonNull(expectedValues, expectedValuesDate, expectedValuesNumber);
        if (actualValue == null) {
            return expected == null;
        } else if (expected == null) {
            return false;
        }

        List<Object> actual = ConditionContextHelper.foldToASCII(getValueSet(actualValue));

        boolean result = true;

        switch (op) {
            case "in":
                result = false;
                for (Object a : actual) {
                    if (expected.contains(a)) {
                        result = true;
                        break;
                    }
                }
                break;
            case "inContains":
                result = false;
                for (Object a : actual) {
                    for (Object b : expected)
                        if (((String) a).contains((String) b)) {
                            result = true;
                            break;
                        }
                }
                break;
            case "notIn":
                for (Object a : actual) {
                    if (expected.contains(a)) {
                        result = false;
                        break;
                    }
                }
                break;
            case "all":
                for (Object e : expected) {
                    if (!actual.contains(e)) {
                        result = false;
                        break;
                    }
                }
                break;
            case "hasNoneOf":
                if (!Collections.disjoint(actual, expected)) {
                    return false;
                }
                break;
            case "hasSomeOf":
                if (Collections.disjoint(actual, expected)) {
                    return false;
                }
                break;

            default:
                throw new IllegalArgumentException("Unknown comparison operator " + op);
        }

        return result;
    }

    @Override
    public boolean eval(Condition condition, Item item, Map<String, Object> context, ConditionEvaluatorDispatcher dispatcher) {
        String op = (String) condition.getParameter("comparisonOperator");
        String name = (String) condition.getParameter("propertyName");

        String expectedValue = ConditionContextHelper.foldToASCII((String) condition.getParameter("propertyValue"));
        Object expectedValueInteger = condition.getParameter("propertyValueInteger");
        Object expectedValueDouble = condition.getParameter("propertyValueDouble");
        Object expectedValueDate = condition.getParameter("propertyValueDate");
        Object expectedValueDateExpr = condition.getParameter("propertyValueDateExpr");

        Object actualValue;
        if (item instanceof Event && "eventType".equals(name)) {
            actualValue = ((Event) item).getEventType();
        } else {
            try {
                long time = System.nanoTime();
                //actualValue = beanUtilsBean.getPropertyUtils().getProperty(item, name);
                actualValue = getPropertyValue(item, name);
                time = System.nanoTime() - time;
                if (time > 5000000L) {
                    logger.info("eval took {} ms for {} {}", time / 1000000L, item.getClass().getName(), name);
                }
            } catch (NullPointerException e) {
                // property not found
                actualValue = null;
            } catch (Exception e) {
                if (!(e instanceof OgnlException)
                        || (!StringUtils.startsWith(e.getMessage(),
                        "source is null for getProperty(null"))) {
                    logger.warn("Error evaluating value for " + item.getClass().getName() + " " + name, e);
                }
                actualValue = null;
            }
        }
        if (actualValue instanceof String) {
            actualValue = ConditionContextHelper.foldToASCII((String) actualValue);
        }

        if (op == null) {
            return false;
        } else if (actualValue == null) {
            return op.equals("missing");
        } else if (op.equals("exists")) {
            return true;
        } else if (op.equals("equals")) {
            if (actualValue instanceof Collection) {
                for (Object o : ((Collection<?>) actualValue)) {
                    if (o instanceof String) {
                        o = ConditionContextHelper.foldToASCII((String) o);
                    }
                    if (compare(o, expectedValue, expectedValueDate, expectedValueInteger, expectedValueDateExpr, expectedValueDouble) == 0) {
                        return true;
                    }
                }
                return false;
            }
            return compare(actualValue, expectedValue, expectedValueDate, expectedValueInteger, expectedValueDateExpr, expectedValueDouble) == 0;
        } else if (op.equals("notEquals")) {
            return compare(actualValue, expectedValue, expectedValueDate, expectedValueInteger, expectedValueDateExpr, expectedValueDouble) != 0;
        } else if (op.equals("greaterThan")) {
            return compare(actualValue, expectedValue, expectedValueDate, expectedValueInteger, expectedValueDateExpr, expectedValueDouble) > 0;
        } else if (op.equals("greaterThanOrEqualTo")) {
            return compare(actualValue, expectedValue, expectedValueDate, expectedValueInteger, expectedValueDateExpr, expectedValueDouble) >= 0;
        } else if (op.equals("lessThan")) {
            return compare(actualValue, expectedValue, expectedValueDate, expectedValueInteger, expectedValueDateExpr, expectedValueDouble) < 0;
        } else if (op.equals("lessThanOrEqualTo")) {
            return compare(actualValue, expectedValue, expectedValueDate, expectedValueInteger, expectedValueDateExpr, expectedValueDouble) <= 0;
        } else if (op.equals("between")) {
            List<?> expectedValuesInteger = (List<?>) condition.getParameter("propertyValuesInteger");
            List<?> expectedValuesDouble = (List<?>) condition.getParameter("propertyValuesDouble");
            List<?> expectedValuesDate = (List<?>) condition.getParameter("propertyValuesDate");
            List<?> expectedValuesDateExpr = (List<?>) condition.getParameter("propertyValuesDateExpr");
            return compare(actualValue, null,
                    (expectedValuesDate != null && expectedValuesDate.size() >= 1) ? getDate(expectedValuesDate.get(0)) : null,
                    (expectedValuesInteger != null && expectedValuesInteger.size() >= 1) ? (Integer) expectedValuesInteger.get(0) : null,
                    (expectedValuesDateExpr != null && expectedValuesDateExpr.size() >= 1) ? (String) expectedValuesDateExpr.get(0) : null,
                    (expectedValuesDouble != null && expectedValuesDouble.size() >= 1) ? (String) expectedValuesDouble.get(0) : null) >= 0
                    &&
                    compare(actualValue, null,
                            (expectedValuesDate != null && expectedValuesDate.size() >= 2) ? getDate(expectedValuesDate.get(1)) : null,
                            (expectedValuesInteger != null && expectedValuesInteger.size() >= 2) ? (Integer) expectedValuesInteger.get(1) : null,
                            (expectedValuesDateExpr != null && expectedValuesDateExpr.size() >= 2) ? (String) expectedValuesDateExpr.get(1) : null,
                            (expectedValuesDouble != null && expectedValuesDouble.size() >= 2) ? (String) expectedValuesDouble.get(1) : null) <= 0;
        } else if (op.equals("contains")) {
            return actualValue.toString().contains(expectedValue);
        } else if (op.equals("notContains")) {
            return !actualValue.toString().contains(expectedValue);
        } else if (op.equals("startsWith")) {
            return actualValue.toString().startsWith(expectedValue);
        } else if (op.equals("endsWith")) {
            return actualValue.toString().endsWith(expectedValue);
        } else if (op.equals("matchesRegex")) {
            return expectedValue != null && Pattern.compile(expectedValue).matcher(actualValue.toString()).matches();
        } else if (op.equals("in") || op.equals("inContains") || op.equals("notIn") || op.equals("hasSomeOf") || op.equals("hasNoneOf") || op.equals("all")) {
            List<?> expectedValues = ConditionContextHelper.foldToASCII((List<?>) condition.getParameter("propertyValues"));
            List<?> expectedValuesInteger = (List<?>) condition.getParameter("propertyValuesInteger");
            List<?> expectedValuesDate = (List<?>) condition.getParameter("propertyValuesDate");
            List<?> expectedValuesDateExpr = (List<?>) condition.getParameter("propertyValuesDateExpr");

            return compareMultivalue(actualValue, expectedValues, expectedValuesDate, expectedValuesInteger, expectedValuesDateExpr, op);
        } else if (op.equals("isDay") && expectedValueDate != null) {
            return yearMonthDayDateFormat.format(getDate(actualValue)).equals(yearMonthDayDateFormat.format(getDate(expectedValueDate)));
        } else if (op.equals("isNotDay") && expectedValueDate != null) {
            return !yearMonthDayDateFormat.format(getDate(actualValue)).equals(yearMonthDayDateFormat.format(getDate(expectedValueDate)));
        }

        return false;
    }

    protected Object getPropertyValue(Item item, String expression) throws Exception {
        if (usePropertyConditionOptimizations) {
            Object result = getHardcodedPropertyValue(item, expression);
            if (!NOT_OPTIMIZED_MARKER.equals(result)) {
                return result;
            }
        }
        if (useOGNLScripting) {
            return getOGNLPropertyValue(item, expression);
        } else {
            logger.warn("OGNL Off. Expression not evaluated on item {} : {}", item.getClass().getName(), expression);
            return null;
        }
    }

    protected Object getHardcodedPropertyValue(Item item, String expression) {
        // the following are optimizations to avoid using the expressions that are slower. The main objective here is
        // to avoid the most used expression that may also trigger calls to the Java Reflection API.
        return getItemProperty(item, expression);
    }

    protected Object getOGNLPropertyValue(Item item, String expression) throws Exception {
        if (expressionFilterFactory.getExpressionFilter("ognl").filter(expression) == null) {
            logger.warn("Expression {} is not allowed !", expression);
            return null;
        }
        OgnlContext ognlContext = getOgnlContext(secureFilteringClassLoader);
        ExpressionAccessor accessor = getPropertyAccessor(item, expression, ognlContext, secureFilteringClassLoader);
        if (accessor != null) {
            try {
                return accessor.get(ognlContext, item);
            } catch (Throwable t) {
                logger.error("Error evaluating expression {} on item {} : {}", expression, item.getClass().getName(), t);
                return null;
            }
        }
        return null;
    }

    private Object getNestedPropertyValue(String expressionPart, Map<String, Object> properties) {
        int nextDotPos = expressionPart.indexOf(".");
        if (nextDotPos > -1) {
            String mapKey = expressionPart.substring(0, nextDotPos);
            Object mapValue = properties.get(mapKey);
            if (mapValue == null) {
                return null;
            }
            String nextExpression = expressionPart.substring(nextDotPos + 1);
            return getNestedPropertyValue(nextExpression, (Map<String, Object>) mapValue);
        } else {
            return properties.get(expressionPart);
        }
    }

    private class ClassLoaderClassResolver extends DefaultClassResolver {
        private ClassLoader classLoader;

        public ClassLoaderClassResolver(ClassLoader classLoader) {
            this.classLoader = classLoader;
        }

        @Override
        protected Class toClassForName(String className) throws ClassNotFoundException {
            return Class.forName(className, true, classLoader);
        }
    }

    private OgnlContext getOgnlContext(ClassLoader classLoader) {
        return (OgnlContext) Ognl.createDefaultContext(null, new MemberAccess() {
                    @Override
                    public Object setup(Map context, Object target, Member member, String propertyName) {
                        return null;
                    }

                    @Override
                    public void restore(Map context, Object target, Member member, String propertyName, Object state) {
                    }

                    @Override
                    public boolean isAccessible(Map context, Object target, Member member, String propertyName) {
                        int modifiers = member.getModifiers();
                        if (target instanceof Item) {
                            if ("getClass".equals(member.getName())) {
                                logger.warn("Target {} and member {} for property {} are not allowed by OGNL security filter", target, member, propertyName);
                                return false;
                            }
                            return Modifier.isPublic(modifiers);
                        }
                        logger.warn("Target {} and member {} for property {} are not allowed by OGNL security filter", target, member, propertyName);
                        return false;
                    }
                }, new ClassLoaderClassResolver(classLoader),
                null);
    }

    private ExpressionAccessor getPropertyAccessor(Item item, String expression, OgnlContext ognlContext, ClassLoader classLoader) throws Exception {
        ExpressionAccessor accessor = null;
        String clazz = item.getClass().getName();
        Map<String, ExpressionAccessor> expressions = expressionCache.get(clazz);
        if (expressions == null) {
            expressions = new HashMap<>();
            expressionCache.put(clazz, expressions);
        } else {
            accessor = expressions.get(expression);
        }
        if (accessor == null) {
            long time = System.nanoTime();
            Thread current = Thread.currentThread();
            ClassLoader contextCL = current.getContextClassLoader();
            try {
                current.setContextClassLoader(classLoader);
                Node node = Ognl.compileExpression(ognlContext, item, expression);
                accessor = node.getAccessor();
            } finally {
                current.setContextClassLoader(contextCL);
            }
            if (accessor != null) {
                expressions.put(expression, accessor);
            } else {
                logger.warn("Unable to compile expression for {} and {}", clazz, expression);
            }
            if (logger.isInfoEnabled()) {
                time = System.nanoTime() - time;
                logger.info("Expression compilation for item={} expression={} took {}", item.getClass().getName(), expression, time / 1000000L);
            }
        }

        return accessor;
    }

    private Date getDate(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Date) {
            return ((Date) value);
        } else {
            JodaDateMathParser parser = new JodaDateMathParser(Joda.forPattern("strictDateOptionalTime||epoch_millis"));
            try {
                return Date.from(parser.parse(value.toString(), System::currentTimeMillis));
            } catch (ElasticsearchParseException e) {
                logger.warn("unable to parse date " + value.toString(), e);
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    private List<Object> getValueSet(Object expectedValue) {
        if (expectedValue instanceof List) {
            return (List<Object>) expectedValue;
        } else if (expectedValue instanceof Collection) {
            return new ArrayList<Object>((Collection<?>) expectedValue);
        } else {
            return Collections.singletonList(expectedValue);
        }
    }

    private Object getEventProperty(Event event, String expression) {
        if (expression.startsWith("properties.")) {
            return getNestedPropertyValue(expression.substring("properties.".length()), event.getProperties());
        }
        if ("scope".equals(expression)) {
            return event.getScope();
        }
        if ("eventType".equals(expression)) {
            return event.getEventType();
        }
        if (expression.startsWith("profile")) {
            if ("profile".equals(expression)) {
                return event.getProfile();
            } else {
                return getProfileProperty(event.getProfile(), expression.substring("profile".length()+1));
            }
        }
        if ("profileId".equals(expression)) {
            return event.getProfileId();
        }
        if (expression.startsWith("session")) {
            if ("session".equals(expression)) {
                return event.getSession();
            } else {
                return getSessionProperty(event.getSession(), expression.substring("session".length()+1));
            }
        }
        if ("sessionId".equals(expression)) {
            return event.getSessionId();
        }
        if (expression.startsWith("source")) {
            if ("source".equals(expression)) {
                return event.getSource();
            } else {
                return getItemProperty(event.getSource(), expression.substring("source".length()+1));
            }
        }
        if (expression.startsWith("target")) {
            if ("target".equals(expression)) {
                return event.getTarget();
            } else {
                return getItemProperty(event.getTarget(), expression.substring("target".length()+1));
            }
        }
        if ("timeStamp".equals(expression)) {
            return event.getTimeStamp();
        }
        if ("itemId".equals(expression)) {
            return event.getItemId();
        }
        if ("itemType".equals(expression)) {
            return event.getItemType();
        }
        logger.warn("Requested unimplemented property {} on Event object", expression);
        return NOT_OPTIMIZED_MARKER;
    }

    private Object getSessionProperty(Session session, String expression) {
        if ("scope".equals(expression)) {
            return session.getScope();
        }
        if ("timeStamp".equals(expression)) {
            return session.getTimeStamp();
        }
        if ("duration".equals(expression)) {
            return session.getDuration();
        }
        if ("size".equals(expression)) {
            return session.getSize();
        }
        if ("lastEventDate".equals(expression)) {
            return session.getLastEventDate();
        }
        if (expression.startsWith("properties.")) {
            return getNestedPropertyValue(expression.substring("properties.".length()), session.getProperties());
        }
        if (expression.startsWith("systemProperties.")) {
            return getNestedPropertyValue(expression.substring("systemProperties.".length()), session.getSystemProperties());
        }
        if ("itemId".equals(expression)) {
            return session.getItemId();
        }
        if ("itemType".equals(expression)) {
            return session.getItemType();
        }
        if (expression.startsWith("profile")) {
            if ("profile".equals(expression)) {
                return session.getProfile();
            } else {
                return getProfileProperty((Profile) session.getProfile(), expression.substring("profile".length()+1));
            }
        }
        if ("profileId".equals(expression)) {
            return session.getProfileId();
        }
        logger.warn("Requested unimplemented property {} on Session object", expression);
        return NOT_OPTIMIZED_MARKER;
    }

    private Object getProfileProperty(Profile profile, String expression) {
        if ("segments".equals(expression)) {
            return profile.getSegments();
        }
        if (expression.startsWith("consents")) {
            if ("consents".equals(expression)) {
                return profile.getConsents();
            } else {
                String consentLookupName = null;
                String leftoverExpression = expression;
                if (expression.startsWith("consents[\"")) {
                    int lookupNameBeginPos = "consents[\"".length();
                    int lookupNameEndPos = expression.indexOf("\"].", lookupNameBeginPos);
                    if (lookupNameEndPos > lookupNameBeginPos) {
                        consentLookupName = expression.substring(lookupNameBeginPos, lookupNameEndPos);
                        leftoverExpression = expression.substring(lookupNameEndPos+3);
                    } else {
                        consentLookupName = expression.substring(lookupNameBeginPos);
                        leftoverExpression = null;
                    }
                } else if (expression.startsWith("consents.")) {
                    int lookupNameBeginPos = "consents.".length();
                    int lookupNameEndPos = expression.indexOf(".", lookupNameBeginPos);
                    if (lookupNameEndPos > lookupNameBeginPos) {
                        consentLookupName = expression.substring(lookupNameBeginPos, lookupNameEndPos);
                        leftoverExpression = expression.substring(lookupNameEndPos+1);
                    } else {
                        consentLookupName = expression.substring(lookupNameBeginPos);
                        leftoverExpression = expression.substring(lookupNameEndPos);
                    }
                }
                Consent consent = profile.getConsents().get(consentLookupName);
                if (consent == null) {
                    return null;
                }
                if (leftoverExpression == null) {
                    return consent;
                }
                return getConsentProperty(consent, leftoverExpression);
            }
        }
        if (expression.startsWith("scores.")) {
            return profile.getScores().get(expression.substring("scores.".length()));
        }
        if (expression.startsWith("properties.")) {
            return getNestedPropertyValue(expression.substring("properties.".length()), profile.getProperties());
        }
        if (expression.startsWith("systemProperties.")) {
            return getNestedPropertyValue(expression.substring("systemProperties.".length()), profile.getSystemProperties());
        }
        if ("itemId".equals(expression)) {
            return profile.getItemId();
        }
        if ("itemType".equals(expression)) {
            return profile.getItemType();
        }
        if ("mergedWith".equals(expression)) {
            return profile.getMergedWith();
        }
        logger.warn("Requested unimplemented property {} on Profile object", expression);
        return NOT_OPTIMIZED_MARKER;
    }

    private Object getCustomItemProperty(CustomItem customItem, String expression) {
        if (expression.startsWith("properties.")) {
            return getNestedPropertyValue(expression.substring("properties.".length()), customItem.getProperties());
        }
        if ("itemId".equals(expression)) {
            return customItem.getItemId();
        }
        if ("itemType".equals(expression)) {
            return customItem.getItemType();
        }
        if ("scope".equals(expression)) {
            return customItem.getScope();
        }
        logger.warn("Requested unimplemented property {} on CustomItem object", expression);
        return NOT_OPTIMIZED_MARKER;
    }

    private Object getRuleProperty(Rule rule, String expression) {
        if ("itemId".equals(expression)) {
            return rule.getItemId();
        }
        if ("itemType".equals(expression)) {
            return rule.getItemType();
        }
        if ("scope".equals(expression)) {
            return rule.getScope();
        }
        logger.warn("Requested unimplemented property {} on Rule object", expression);
        return NOT_OPTIMIZED_MARKER;
    }

    private Object getItemProperty(Item item, String expression) {
        if (item instanceof Profile) {
            return getProfileProperty((Profile) item, expression);
        } else if (item instanceof Session) {
            return getSessionProperty((Session) item, expression);
        } else if (item instanceof Rule) {
            return getRuleProperty((Rule) item, expression);
        } else if (item instanceof Event) {
            return getEventProperty((Event) item, expression);
        } else if (item instanceof CustomItem) {
            return getCustomItemProperty((CustomItem) item, expression);
        } else {
            logger.warn("Requested unrecognized property {} on {} class", expression, item.getClass().getName());
            return NOT_OPTIMIZED_MARKER;
        }
    }

    private Object getConsentProperty(Consent consent, String expression) {
        if ("typeIdentifier".equals(expression)) {
            return consent.getTypeIdentifier();
        } else if ("scope".equals(expression)) {
            return consent.getScope();
        } else if ("status".equals(expression)) {
            return consent.getStatus();
        } else if ("statusDate".equals(expression)) {
            return consent.getStatusDate();
        } else if ("revokeDate".equals(expression)) {
            return consent.getRevokeDate();
        } else {
            logger.warn("Requested unrecognized property {} on Consent object {}", expression, consent);
            return NOT_OPTIMIZED_MARKER;
        }
    }
}
