/*
 * 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.marmotta.kiwi.sparql.builder.eval;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import org.apache.marmotta.commons.util.DateUtils;
import org.apache.marmotta.kiwi.model.rdf.KiWiNode;
import org.apache.marmotta.kiwi.sparql.builder.SQLBuilder;
import org.apache.marmotta.kiwi.sparql.builder.ValueType;
import org.apache.marmotta.kiwi.sparql.builder.collect.OPTypeFinder;
import org.apache.marmotta.kiwi.sparql.builder.model.SQLVariable;
import org.apache.marmotta.kiwi.sparql.function.NativeFunction;
import org.apache.marmotta.kiwi.sparql.function.NativeFunctionRegistry;
import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.vocabulary.FN;
import org.openrdf.model.vocabulary.XMLSchema;
import org.openrdf.query.algebra.*;
import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Evaluate a SPARQL ValueExpr by translating it into a SQL expression.
 *
 * @author Sebastian Schaffert (sschaffert@apache.org)
 */
public class ValueExpressionEvaluator extends QueryModelVisitorBase<RuntimeException> {

    private static Logger log = LoggerFactory.getLogger(ValueExpressionEvaluator.class);

    /**
     * Date format used for SQL timestamps.
     */
    private static final DateFormat sqlDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");

    /**
     * Reference to the registry of natively supported functions with parameter and return types as well as SQL translation
     */
    private static NativeFunctionRegistry functionRegistry = NativeFunctionRegistry.getInstance();

    // used by BNodeGenerator
    private static Random anonIdGenerator = new Random();


    private StringBuilder builder = new StringBuilder();

    private Deque<ValueType> optypes = new ArrayDeque<>();

    private SQLBuilder parent;

    public ValueExpressionEvaluator(ValueExpr expr, SQLBuilder parent) {
        this(expr,parent, ValueType.NODE);
    }

    public ValueExpressionEvaluator(ValueExpr expr, SQLBuilder parent, ValueType optype) {
        this.parent = parent;

        optypes.push(optype);

        if(log.isTraceEnabled()) {
            long start = System.currentTimeMillis();
            expr.visit(this);
            log.trace("expression evaluated in {} ms", (System.currentTimeMillis()-start));
        } else {
            expr.visit(this);
        }
    }


    /**
     * Create the actual SQL string generated by this evaluator.
     *
     * @return
     */
    public String build() {
        return builder.toString();
    }

    @Override
    public void meet(And node) throws RuntimeException {
        builder.append("(");
        node.getLeftArg().visit(this);
        builder.append(" AND ");
        node.getRightArg().visit(this);
        builder.append(")");
    }

    @Override
    public void meet(Or node) throws RuntimeException {
        builder.append("(");
        node.getLeftArg().visit(this);
        builder.append(" OR ");
        node.getRightArg().visit(this);
        builder.append(")");
    }

    @Override
    public void meet(Not node) throws RuntimeException {
        builder.append("NOT (");
        node.getArg().visit(this);
        builder.append(")");
    }

    @Override
    public void meet(Exists node) throws RuntimeException {
        // TODO: need to make sure that variables of the parent are visible in the subquery
        //       - pattern names need to be unique even in subqueries
        //       - variable lookup for expressions in the subquery need to refer to the parent
        SQLBuilder sq_builder = new SQLBuilder(node.getSubQuery(), parent.getBindings(), parent.getDataset(), parent.getConverter(), parent.getDialect(), "_", Collections.EMPTY_SET, copyVariables(parent.getVariables()));

        builder.append("EXISTS (").append(sq_builder.build()).append(")");
    }

    @Override
    public void meet(FunctionCall fc) throws RuntimeException {
        // special optimizations for frequent cases with variables
        if((XMLSchema.DOUBLE.toString().equals(fc.getURI()) || XMLSchema.FLOAT.toString().equals(fc.getURI()) ) && fc.getArgs().size() == 1) {
            optypes.push(ValueType.DOUBLE);
            fc.getArgs().get(0).visit(this);
            optypes.pop();
        } else if((XMLSchema.INTEGER.toString().equals(fc.getURI()) || XMLSchema.INT.toString().equals(fc.getURI())) && fc.getArgs().size() == 1) {
            optypes.push(ValueType.INT);
            fc.getArgs().get(0).visit(this);
            optypes.pop();
        } else if(XMLSchema.BOOLEAN.toString().equals(fc.getURI()) && fc.getArgs().size() == 1) {
            optypes.push(ValueType.BOOL);
            fc.getArgs().get(0).visit(this);
            optypes.pop();
        } else if(XMLSchema.DATE.toString().equals(fc.getURI()) && fc.getArgs().size() == 1) {
            optypes.push(ValueType.DATE);
            fc.getArgs().get(0).visit(this);
            optypes.pop();
        } else {

            String fnUri = fc.getURI();

            String[] args = new String[fc.getArgs().size()];

            NativeFunction nf = functionRegistry.get(fnUri);

            if (nf != null && nf.isSupported(parent.getDialect())) {

                for (int i = 0; i < args.length; i++) {
                    args[i] = new ValueExpressionEvaluator(fc.getArgs().get(i), parent, nf.getArgumentType(i)).build();
                }

                if (optypes.peek() != nf.getReturnType()) {
                    builder.append(castExpression(nf.getNative(parent.getDialect(), args), optypes.peek()));
                } else {
                    builder.append(nf.getNative(parent.getDialect(), args));
                }
            } else {
                throw new IllegalArgumentException("the function " + fnUri + " is not supported by the SQL translation");
            }
        }

    }

    @Override
    public void meet(Avg node) throws RuntimeException {
        builder.append("AVG(");
        optypes.push(ValueType.DOUBLE);
        node.getArg().visit(this);
        optypes.pop();
        builder.append(")");
    }

    @Override
    public void meet(BNodeGenerator gen) throws RuntimeException {
        if(gen.getNodeIdExpr() != null) {
            // get value of argument and express it as string
            optypes.push(ValueType.STRING);
            gen.getNodeIdExpr().visit(this);
            optypes.pop();
        } else {
            builder.append("'").append(Long.toHexString(System.currentTimeMillis())).append(Integer.toHexString(anonIdGenerator.nextInt(1000))).append("'");
        }
    }

    @Override
    public void meet(Bound node) throws RuntimeException {
        ValueExpr arg = node.getArg();

        builder.append("(");
        optypes.push(ValueType.NODE);
        arg.visit(this);
        optypes.pop();
        builder.append(" IS NOT NULL)");
    }

    @Override
    public void meet(Coalesce node) throws RuntimeException {
        builder.append("COALESCE(");
        for(Iterator<ValueExpr> it = node.getArguments().iterator(); it.hasNext(); ) {
            it.next().visit(this);
            if(it.hasNext()) {
                builder.append(", ");
            }
        }
        builder.append(")");
    }

    @Override
    public void meet(Compare cmp) throws RuntimeException {
        optypes.push(new OPTypeFinder(cmp).coerce());
        cmp.getLeftArg().visit(this);
        builder.append(getSQLOperator(cmp.getOperator()));
        cmp.getRightArg().visit(this);
        optypes.pop();
    }

    @Override
    public void meet(Count node) throws RuntimeException {
        builder.append("COUNT(");

        if(node.isDistinct()) {
            builder.append("DISTINCT ");
        }

        if(node.getArg() == null) {
            // this is a weird special case where we need to expand to all variables selected in the query wrapped
            // by the group; we cannot simply use "*" because the concept of variables is a different one in SQL,
            // so instead we construct an ARRAY of the bindings of all variables

            List<String> countVariables = new ArrayList<>();
            for(SQLVariable v : parent.getVariables().values()) {
                if(v.getProjectionType() == ValueType.NONE) {
                    Preconditions.checkState(v.getExpressions().size() > 0, "no expressions available for variable");

                    countVariables.add(v.getExpressions().get(0));
                }
            }
            builder.append("ARRAY[");
            Joiner.on(',').appendTo(builder, countVariables);
            builder.append("]");

        } else {
            optypes.push(ValueType.NODE);
            node.getArg().visit(this);
            optypes.pop();
        }
        builder.append(")");
    }


    @Override
    public void meet(GroupConcat node) throws RuntimeException {
        if(node.getSeparator() == null) {
            builder.append(parent.getDialect().getGroupConcat(new ValueExpressionEvaluator(node.getArg(), parent, ValueType.STRING).build(), null, node.isDistinct()));
        } else {
            builder.append(parent.getDialect().getGroupConcat(
                    new ValueExpressionEvaluator(node.getArg(), parent, ValueType.STRING).build(),
                    new ValueExpressionEvaluator(node.getSeparator(), parent, ValueType.STRING).build(),
                    node.isDistinct()
            ));
        }
    }


    @Override
    public void meet(If node) throws RuntimeException {
        builder.append("CASE WHEN ");

        optypes.push(ValueType.BOOL);
        node.getCondition().visit(this);
        optypes.pop();

        optypes.push(new OPTypeFinder(node).coerce());
        builder.append(" THEN ");
        node.getResult().visit(this);
        builder.append(" ELSE ");
        node.getAlternative().visit(this);
        builder.append(" END");
        optypes.pop();
    }


    @Override
    public void meet(IsBNode node) throws RuntimeException {
        ValueExpr arg = node.getArg();

        // operator must be a variable or a constant
        if(arg instanceof ValueConstant) {
            builder.append(Boolean.toString(((ValueConstant) arg).getValue() instanceof BNode));
        } else if(arg instanceof Var) {
            String var = getVariableAlias((Var) arg);

            builder.append(var).append(".ntype = 'bnode'");
        }
    }

    @Override
    public void meet(IsLiteral node) throws RuntimeException {
        ValueExpr arg = node.getArg();

        // operator must be a variable or a constant
        if (arg instanceof ValueConstant) {
            builder.append(Boolean.toString(((ValueConstant) arg).getValue() instanceof Literal));
        } else if(arg instanceof Var) {
            String var = getVariableAlias((Var) arg);

            Preconditions.checkState(var != null, "no alias available for variable");

            builder.append("(")
                    .append(var)
                    .append(".ntype = 'string' OR ")
                    .append(var)
                    .append(".ntype = 'int' OR ")
                    .append(var)
                    .append(".ntype = 'double' OR ")
                    .append(var)
                    .append(".ntype = 'date' OR ")
                    .append(var)
                    .append(".ntype = 'boolean')");
        }
    }

    @Override
    public void meet(IsNumeric node) throws RuntimeException {
        ValueExpr arg = node.getArg();

        // operator must be a variable or a constant
        if (arg instanceof ValueConstant) {
            try {
                Double.parseDouble(((ValueConstant) arg).getValue().stringValue());
                builder.append(Boolean.toString(true));
            } catch (NumberFormatException ex) {
                builder.append(Boolean.toString(false));
            }
        } else if(arg instanceof Var) {
            String var = getVariableAlias((Var) arg);

            Preconditions.checkState(var != null, "no alias available for variable");

            builder.append("(")
                    .append(var)
                    .append(".ntype = 'int' OR ")
                    .append(var)
                    .append(".ntype = 'double')");
        }
    }

    @Override
    public void meet(IsResource node) throws RuntimeException {
        ValueExpr arg = node.getArg();

        // operator must be a variable or a constant
        if(arg instanceof ValueConstant) {
            builder.append(Boolean.toString(((ValueConstant) arg).getValue() instanceof URI || ((ValueConstant) arg).getValue() instanceof BNode));
        } else if(arg instanceof Var) {
            String var = getVariableAlias((Var) arg);

            Preconditions.checkState(var != null, "no alias available for variable");

            builder .append("(")
                    .append(var)
                    .append(".ntype = 'uri' OR ")
                    .append(var)
                    .append(".ntype = 'bnode')");
        }
    }

    @Override
    public void meet(IsURI node) throws RuntimeException {
        ValueExpr arg = node.getArg();

        // operator must be a variable or a constant
        if(arg instanceof ValueConstant) {
            builder.append(Boolean.toString(((ValueConstant) arg).getValue() instanceof URI));
        } else if(arg instanceof Var) {
            String var = getVariableAlias((Var) arg);

            Preconditions.checkState(var != null, "no alias available for variable");

            builder.append(var).append(".ntype = 'uri'");
        }
    }

    @Override
    public void meet(IRIFunction fun) throws RuntimeException {
        if(fun.getBaseURI() != null) {

            String ex = new ValueExpressionEvaluator(fun.getArg(), parent, ValueType.STRING).build();

            builder
                    .append("CASE WHEN position(':' IN ").append(ex).append(") > 0 THEN ").append(ex)
                    .append(" ELSE ").append(functionRegistry.get(FN.CONCAT.stringValue()).getNative(parent.getDialect(), "'" + fun.getBaseURI() + "'", ex))
                    .append(" END ");
        } else {
            // get value of argument and express it as string
            optypes.push(ValueType.STRING);
            fun.getArg().visit(this);
            optypes.pop();
        }
    }

    @Override
    public void meet(Label node) throws RuntimeException {
        optypes.push(ValueType.STRING);
        node.getArg().visit(this);
        optypes.pop();
    }

    @Override
    public void meet(Lang lang) throws RuntimeException {
        if(lang.getArg() instanceof Var) {
            String var = getVariableAlias((Var) lang.getArg());
            Preconditions.checkState(var != null, "no alias available for variable");

            builder.append(var);
            builder.append(".lang");
        }
    }

    @Override
    public void meet(LangMatches lm) throws RuntimeException {
        ValueConstant pattern = (ValueConstant) lm.getRightArg();

        if(pattern.getValue().stringValue().equals("*")) {
            lm.getLeftArg().visit(this);
            builder.append(" LIKE '%'");
        } else if(pattern.getValue().stringValue().equals("")) {
            lm.getLeftArg().visit(this);
            builder.append(" IS NULL");
        } else {
            builder.append("(");
            lm.getLeftArg().visit(this);
            builder.append(" = '");
            builder.append(pattern.getValue().stringValue().toLowerCase());
            builder.append("' OR ");
            lm.getLeftArg().visit(this);
            builder.append(" LIKE '");
            builder.append(pattern.getValue().stringValue().toLowerCase());
            builder.append("-%' )");
        }
    }

    @Override
    public void meet(Like node) throws RuntimeException {
        if(node.isCaseSensitive()) {
            optypes.push(ValueType.STRING);
            node.getArg().visit(this);
            optypes.pop();

            builder.append(" LIKE ");
            node.getPattern();
        } else {
            builder.append(parent.getDialect().getILike(new ValueExpressionEvaluator(node.getArg(),parent, ValueType.STRING).build(), node.getOpPattern()));
        }

    }


    @Override
    public void meet(LocalName node) throws RuntimeException {
        super.meet(node);
    }

    @Override
    public void meet(MathExpr expr) throws RuntimeException {
        ValueType ot = new OPTypeFinder(expr).coerce();

        if(ot == ValueType.STRING) {
            if(expr.getOperator() == MathExpr.MathOp.PLUS) {
                builder.append(functionRegistry.get(FN.CONCAT.stringValue()).getNative(parent.getDialect(),new ValueExpressionEvaluator(expr.getLeftArg(), parent, ot).build(), new ValueExpressionEvaluator(expr.getRightArg(), parent, ot).build()));
            } else {
                throw new IllegalArgumentException("operation "+expr.getOperator()+" is not supported on strings");
            }
        } else {
            if(ot == ValueType.NODE || ot == ValueType.TERM) {
                ot = ValueType.DOUBLE;
            }

            optypes.push(ot);
	    builder.append("(");
            expr.getLeftArg().visit(this);
	    builder.append(")");
            builder.append(getSQLOperator(expr.getOperator()));
	    builder.append("(");
            expr.getRightArg().visit(this);
	    builder.append(")");
            optypes.pop();
        }
    }

    @Override
    public void meet(Max node) throws RuntimeException {
        builder.append("MAX(");
        optypes.push(ValueType.DOUBLE);
        node.getArg().visit(this);
        optypes.pop();
        builder.append(")");
    }

    @Override
    public void meet(Min node) throws RuntimeException {
        builder.append("MIN(");
        optypes.push(ValueType.DOUBLE);
        node.getArg().visit(this);
        optypes.pop();
        builder.append(")");
    }

    @Override
    public void meet(Regex re) throws RuntimeException {
        builder.append(optimizeRegexp(
                new ValueExpressionEvaluator(re.getArg(), parent, ValueType.STRING).build(),
                new ValueExpressionEvaluator(re.getPatternArg(), parent, ValueType.STRING).build(),
                re.getFlagsArg()
        ));
    }

    @Override
    public void meet(SameTerm cmp) throws RuntimeException {
        // covered by value binding in variables
        optypes.push(ValueType.TERM);
        cmp.getLeftArg().visit(this);
        builder.append(" = ");
        cmp.getRightArg().visit(this);
        optypes.pop();
    }

    @Override
    public void meet(Str node) throws RuntimeException {
        optypes.push(ValueType.STRING);
        node.getArg().visit(this);
        optypes.pop();
    }

    @Override
    public void meet(Sum node) throws RuntimeException {
        builder.append("SUM(");
        optypes.push(ValueType.DOUBLE);
        node.getArg().visit(this);
        optypes.pop();
        builder.append(")");
    }

    @Override
    public void meet(Var node) throws RuntimeException {
        // distinguish between the case where the variable is plain and the variable is bound
        SQLVariable sv = parent.getVariables().get(node.getName());

        if(sv == null) {
            builder.append("NULL");
        } else if(sv.getBindings().size() > 0) {
            // in case the variable is actually an alias for an expression, we evaluate that expression instead, effectively replacing the
            // variable occurrence with its value
            sv.getBindings().get(0).visit(this);
        } else {
            String var = sv.getAlias();

            if(sv.getProjectionType() != ValueType.NODE && sv.getProjectionType() != ValueType.NONE) {
                // in case the variable represents a constructed or bound value instead of a node, we need to
                // use the SQL expression as value; SQL should take care of proper casting...
                // TODO: explicit casting needed?
                builder.append(sv.getExpressions().get(0));
            } else {
                // in case the variable represents an entry from the NODES table (i.e. has been bound to a node
                // in the database, we take the NODES alias and resolve to the correct column according to the
                // operator type
                switch (optypes.peek()) {
                    case STRING:
                        Preconditions.checkState(var != null, "no alias available for variable");
                        builder.append(var).append(".svalue");
                        break;
                    case INT:
                        Preconditions.checkState(var != null, "no alias available for variable");
                        builder.append(var).append(".ivalue");
                        break;
                    case DECIMAL:
                    case DOUBLE:
                        Preconditions.checkState(var != null, "no alias available for variable");
                        builder.append(var).append(".dvalue");
                        break;
                    case BOOL:
                        Preconditions.checkState(var != null, "no alias available for variable");
                        builder.append(var).append(".bvalue");
                        break;
                    case DATE:
                        Preconditions.checkState(var != null, "no alias available for variable");
                        builder.append(var).append(".tvalue");
                        break;
                    case TZDATE:
                        Preconditions.checkState(var != null, "no alias available for variable");
                        builder.append(parent.getDialect().getDateTimeTZ(var));
                        break;
                    case URI:
                        Preconditions.checkState(var != null, "no alias available for variable");
                        builder.append(var).append(".svalue");
                        break;
                    case TERM:
                    case NODE:
                        if(sv.getExpressions().size() > 0) {
                            // this allows us to avoid joins with the nodes table for simple expressions that only need the ID
                            builder.append(sv.getExpressions().get(0));
                        } else {
                            Preconditions.checkState(var != null, "no alias available for variable");
                            builder.append(var).append(".id");
                        }
                        break;
                }
            }
        }
    }

    @Override
    public void meet(ValueConstant node) throws RuntimeException {
        String val = node.getValue().stringValue();

            switch (optypes.peek()) {
                case STRING:
                case URI:
                    builder.append("'").append(val).append("'");
                    break;
                case INT:
                    builder.append(Integer.parseInt(val));
                    break;
                case DECIMAL:
                case DOUBLE:
                    builder.append(Double.parseDouble(val));
                    break;
                case BOOL:
                    builder.append(Boolean.parseBoolean(val));
                    break;
                case DATE:
                    builder.append("'").append(sqlDateFormat.format(DateUtils.parseDate(val))).append("'");
                    break;

                // in this case we should return a node ID and also need to make sure it actually exists
                case TERM:
                case NODE:
                    KiWiNode n = parent.getConverter().convert(node.getValue());
                    builder.append(n.getId());
                    break;

                default: throw new IllegalArgumentException("unsupported value type: " + optypes.peek());
            }
    }

    private String getVariableAlias(Var var) {
        return parent.getVariables().get(var.getName()).getAlias();
    }


    private String getVariableAlias(String varName) {
        return parent.getVariables().get(varName).getAlias();
    }

    /**
     * Copy variables from the set to a new set suitable for a subquery; this allows passing over variable expressions
     * from parent queries to subqueries without the subquery adding expressions that are then not visible outside
     * @param variables
     * @return
     */
    private static Map<String, SQLVariable> copyVariables(Map<String, SQLVariable> variables) {
        Map<String,SQLVariable> copy = new HashMap<>();
        try {
            for(Map.Entry<String,SQLVariable> entry : variables.entrySet()) {
                copy.put(entry.getKey(), (SQLVariable) entry.getValue().clone());
            }
        } catch (CloneNotSupportedException e) {
            log.error("could not clone SQL variable:",e);
        }

        return copy;
    }

    private String castExpression(String arg, ValueType type) {
        if(type == null) {
            return arg;
        }

        switch (type) {
            case DECIMAL:
                return functionRegistry.get(XMLSchema.DECIMAL).getNative(parent.getDialect(), arg);
            case DOUBLE:
                return functionRegistry.get(XMLSchema.DOUBLE).getNative(parent.getDialect(), arg);
            case INT:
                return functionRegistry.get(XMLSchema.INTEGER).getNative(parent.getDialect(), arg);
            case BOOL:
                return functionRegistry.get(XMLSchema.BOOLEAN).getNative(parent.getDialect(), arg);
            case DATE:
                return functionRegistry.get(XMLSchema.DATETIME).getNative(parent.getDialect(), arg);
            case STRING:
                return arg;
            case NODE:
                return arg;
            default:
                return arg;
        }
    }

    private static String getSQLOperator(Compare.CompareOp op) {
        switch (op) {
            case EQ: return " = ";
            case GE: return " >= ";
            case GT: return " > ";
            case LE: return " <= ";
            case LT: return " < ";
            case NE: return " <> ";
        }
        throw new IllegalArgumentException("unsupported operator type for comparison: "+op);
    }


    private static String getSQLOperator(MathExpr.MathOp op) {
        switch (op) {
            case PLUS: return " + ";
            case MINUS: return " - ";
            case DIVIDE: return " / ";
            case MULTIPLY: return " * ";
        }
        throw new IllegalArgumentException("unsupported operator type for math expression: "+op);
    }

    /**
     * Test if the regular expression given in the pattern can be simplified to a LIKE SQL statement; these are
     * considerably more efficient to evaluate in most databases, so in case we can simplify, we return a LIKE.
     *
     * @param value
     * @param pattern
     * @return
     */
    private String optimizeRegexp(String value, String pattern, ValueExpr flags) {
        String _flags = flags != null && flags instanceof ValueConstant ? ((ValueConstant)flags).getValue().stringValue() : null;

        String simplified = pattern;

        // apply simplifications

        // remove SQL quotes at beginning and end
        simplified = simplified.replaceFirst("^'","");
        simplified = simplified.replaceFirst("'$","");


        // remove .* at beginning and end, they are the default anyways
        simplified = simplified.replaceFirst("^\\.\\*","");
        simplified = simplified.replaceFirst("\\.\\*$","");

        // replace all occurrences of % with \% and _ with \_, as they are special characters in SQL
        simplified = simplified.replaceAll("%","\\%");
        simplified = simplified.replaceAll("_","\\_");

        // if pattern now does not start with a ^, we put a "%" in front
        if(!simplified.startsWith("^")) {
            simplified = "%" + simplified;
        } else {
            simplified = simplified.substring(1);
        }

        // if pattern does not end with a "$", we put a "%" at the end
        if(!simplified.endsWith("$")) {
            simplified = simplified + "%";
        } else {
            simplified = simplified.substring(0,simplified.length()-1);
        }

        // replace all non-escaped occurrences of .* with %
        simplified = simplified.replaceAll("(?<!\\\\)\\.\\*","%");

        // replace all non-escaped occurrences of .+ with _%
        simplified = simplified.replaceAll("(?<!\\\\)\\.\\+","_%");

        // the pattern is not simplifiable if the simplification still contains unescaped regular expression constructs
        Pattern notSimplifiable = Pattern.compile("(?<!\\\\)[\\.\\*\\+\\{\\}\\[\\]\\|]");

        if(notSimplifiable.matcher(simplified).find()) {
            return parent.getDialect().getRegexp(value, pattern, _flags);
        } else {
            if(!simplified.startsWith("%") && !simplified.endsWith("%")) {
                if(StringUtils.containsIgnoreCase(_flags, "i")) {
                    return String.format("lower(%s) = lower('%s')", value, simplified);
                } else {
                    return String.format("%s = '%s'", value, simplified);
                }
            } else {
                if(StringUtils.containsIgnoreCase(_flags,"i")) {
                    return parent.getDialect().getILike(value, "'" + simplified + "'");
                } else {
                    return value + " LIKE '"+simplified+"'";
                }
            }
        }

    }

}
