/*******************************************************************************
 * Copyright (c) 2018, 2019 Ericsson
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License 2.0 which
 * accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.tracecompass.internal.provisional.tmf.core.model.filter.parser;

import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.Tree;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.common.core.format.DecimalUnitFormat;
import org.eclipse.tracecompass.common.core.format.SubSecondTimeWithUnitFormat;
import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
import org.eclipse.tracecompass.tmf.core.filter.model.ITmfFilterTreeNode;
import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterAspectNode;
import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterCompareNode;
import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterContainsNode;
import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterEqualsNode;
import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterMatchesNode;
import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterOrNode;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.util.Pair;
import org.eclipse.tracecompass.tmf.filter.parser.FilterParserParser;

/**
 * Compilation unit for a simple filter expression
 *
 * @author Jean-Christian Kouame
 *
 */
public class FilterSimpleExpressionCu implements IFilterCu {

    private static final Format DECIMAL_FORMAT = new DecimalUnitFormat();

    private final String fField;
    private final String fOperator;
    private final @Nullable String fValue;

    /**
     * Constructor
     *
     * @param field
     *            The field to look for
     * @param op
     *            The operator to use for the test
     * @param value
     *            The value to to test
     */
    public FilterSimpleExpressionCu(String field, String op, @Nullable String value) {
        fField = field;
        fOperator = op;
        fValue = value;
    }

    /**
     * Get the filter field parameter
     *
     * @return the field parameter
     */
    protected String getField() {
        return fField;
    }

    /**
     * Get the filter operator
     *
     * @return The filter operator
     */
    protected String getOperator() {
        return fOperator;
    }

    /**
     * Get the filter value parameter
     *
     * @return The value parameter
     */
    protected @Nullable String getValue() {
        return fValue;
    }

    /**
     * Compile a simple filter expression compilation unit from a tree
     *
     * @param tree
     *            The input tree
     * @return The simple filter expression compilation unit
     */
    public static @Nullable FilterSimpleExpressionCu compile(CommonTree tree) {
        if (tree.getToken() == null) {
            return null;
        }

        int childCount = tree.getChildCount();
        switch (tree.getToken().getType()) {
        case FilterParserParser.CONSTANT:
        case FilterParserParser.PAR_CONSTANT:
            StringBuilder paragraph = new StringBuilder();
            extractParagraph(tree, paragraph, 0, childCount);
            return new FilterSimpleExpressionCu(IFilterStrings.WILDCARD, IFilterStrings.MATCHES, paragraph.toString().trim());
        case FilterParserParser.OPERATION:
            String left = Objects.requireNonNull(tree.getChild(0).getText());
            String op = Objects.requireNonNull(tree.getChild(1).getText());
            String right = tree.getChild(2).getText();
            return new FilterSimpleExpressionCu(left, op, right);
        case FilterParserParser.OPERATION1:
            String left1 = Objects.requireNonNull(tree.getChild(0).getText());
            String op1 = Objects.requireNonNull(tree.getChild(1).getText());
            String right1 = null;
            return new FilterSimpleExpressionCu(left1, op1, right1);
        case FilterParserParser.OPERATION2:
        case FilterParserParser.OPERATION4:
        case FilterParserParser.OPERATION5:
            StringBuilder builder = new StringBuilder();
            int index = extractParagraph(tree, builder, 0, childCount);
            String left2 = builder.toString().trim();
            String op2 = Objects.requireNonNull(tree.getChild(index++).getText());
            builder = new StringBuilder();
            extractParagraph(tree, builder, index, childCount);
            String right2 = builder.toString().trim();
            return new FilterSimpleExpressionCu(left2, op2, right2);
        case FilterParserParser.OPERATION3:
            StringBuilder builder1 = new StringBuilder();
            int index1 = extractParagraph(tree, builder1, 0, childCount);
            String left3 = builder1.toString().trim();
            String op3 = Objects.requireNonNull(tree.getChild(index1).getText());
            String right3 = null;
            return new FilterSimpleExpressionCu(left3, op3, right3);
        case FilterParserParser.ROOT2:
            if (childCount == 0 || (childCount == 2 && tree.getChild(1).getType() != FilterParserParser.CONSTANT)) {
                return null;
            }

            boolean negate = tree.getChild(0).getText().equals(IFilterStrings.NOT);
            CommonTree expression = Objects.requireNonNull((CommonTree) tree.getChild(childCount - 1));
            FilterSimpleExpressionCu compiled = negate ? FilterSimpleExpressionNotCu.compile(expression) : FilterSimpleExpressionCu.compile(expression);
            return compiled;
        default:
            break;
        }
        return null;
    }

    private static int extractParagraph(CommonTree tree, StringBuilder builder, int index, int count) {
        String separator = " "; //$NON-NLS-1$
        int i;
        boolean stop = false;
        for (i = index; i < count && !stop; i++) {
            Tree child = tree.getChild(i);
            if (child.getType() != FilterParserParser.TEXT) {
                stop = true;
                continue;
            }
            builder.append(child.getText());
            builder.append(separator);
        }
        return --i;
    }

    /**
     * Generates a filter simple expression runtime object
     *
     * @return The filter simple expression
     */
    public FilterSimpleExpression generate() {
        return new FilterSimpleExpression(fField, getConditionOperator(fOperator), fValue);
    }

    /**
     * Get the condition predicate for the operator
     *
     * @param equationType
     *            The operator to convert to predicate
     * @return The condition predicate
     */
    protected static ConditionOperator getConditionOperator(String equationType) {
        switch (equationType) {
        case IFilterStrings.EQUAL:
            return ConditionOperator.EQ;
        case IFilterStrings.NOT_EQUAL:
            return ConditionOperator.NE;
        case IFilterStrings.MATCHES:
            return ConditionOperator.MATCHES;
        case IFilterStrings.CONTAINS:
            return ConditionOperator.CONTAINS;
        case IFilterStrings.PRESENT:
            return ConditionOperator.PRESENT;
        case IFilterStrings.GT:
            return ConditionOperator.GT;
        case IFilterStrings.LT:
            return ConditionOperator.LT;
        default:
            throw new IllegalArgumentException("FilterSimpleExpression: invalid comparison operator."); //$NON-NLS-1$
        }
    }

    /**
     * Condition operators used to compare 2 values together. The first value
     * should be the internal value and the second value the value entered by
     * the user or filter.
     */
    protected enum ConditionOperator implements BiPredicate<Object, Object> {
        /** equal */
        EQ((i, j) -> equals(i, j)),
        /** not equal */
        NE((i, j) -> !equals(i, j)),
        /** Matches */
        MATCHES(matchFunc()),
        /** Contains */
        CONTAINS((i, j) -> String.valueOf(i).contains(String.valueOf(j))),
        /** Less than */
        LT((i, j) -> numericalCompare(i, j) < 0),
        /** Greater than */
        GT((i, j) -> numericalCompare(i, j) > 0),
        /** Field is present */
        PRESENT((i, j) -> true);

        private final BiFunction<Object, Object, Boolean> fCmpFunction;

        ConditionOperator(BiFunction<Object, Object, Boolean> cmpFunction) {
            fCmpFunction = cmpFunction;
        }

        private static BiFunction<Object, Object, Boolean> matchFunc() {
            return (i, j) -> {
                Pattern filterPattern = null;
                Object value = j;
                if (j instanceof Pair) {
                    Pair<?, ?> pair = (Pair<?, ?>) j;
                    if (pair.getFirst() instanceof Pattern) {
                        filterPattern = (Pattern) pair.getFirst();
                    }
                    value = pair.getSecond();
                }
                /*
                 * 'value' is the value entered by the user, if it has been
                 * converted to a Number, the equality check is better suited as
                 * the format (hex, decimal) is considered
                 */
                if (value instanceof Number && equals(i, value)) {
                    return true;
                }
                if (filterPattern != null) {
                    return filterPattern.matcher(String.valueOf(i)).find();
                }
                return false;
            };
        }

        private static boolean equals(Object i, Object j) {
            // Are objects equal
            if (Objects.equals(i, j)) {
                return true;
            }
            // Are their String representation equals
            if (Objects.equals(String.valueOf(i), String.valueOf(j))) {
                return true;
            }
            // Try to convert them to number and see if they are the same
            Number number1 = toNumber(i);
            if (number1 == null) {
                return false;
            }
            Number number2 = toNumber(j);
            if (number2 == null) {
                return false;
            }
            if (number1 instanceof Double || number2 instanceof Double
                    || number1 instanceof Float || number2 instanceof Float) {
                return number1.doubleValue() == number2.doubleValue();
            }
            return number1.longValue() == number2.longValue();
        }

        private static int numericalCompare(Object i, Object j) {
            Number number1 = toNumber(i);
            Number number2 = toNumber(j);
            if (number2 == null || number1 == null) {
                // Compare their string representation
                return String.valueOf(i).compareTo(String.valueOf(j));
            } else if (number1 instanceof Double || number2 instanceof Double
                    || number1 instanceof Float || number2 instanceof Float) {
                return Double.compare(number1.doubleValue(), number2.doubleValue());
            }
            return Long.compare(number1.longValue(), number2.longValue());
        }

        private static @Nullable Number toNumber(Object value) {
            if (value instanceof Number) {
                return (Number) value;
            }
            String val = String.valueOf(value);
            try {
                return Long.decode(val);
            } catch (NumberFormatException e) {
            }

            // Try to use some formatters to parse the value
            ParsePosition pos = new ParsePosition(0);
            Number parsed = NumberFormat.getInstance().parse(val, pos);
            // The full string should have been parsed, not just the first
            // numerical characters
            if (pos.getErrorIndex() < 0 && pos.getIndex() == val.length()) {
                return parsed;
            }

            // Try the decimal with unit formatter
            pos = new ParsePosition(0);
            Object parsedObj = DECIMAL_FORMAT.parseObject(val, pos);
            // The full string should have been parsed, not just the first
            // numerical characters
            if (pos.getErrorIndex() < 0 && pos.getIndex() == val.length() && parsedObj instanceof Number) {
                return (Number) parsedObj;
            }

            // Try the duration formatter
            pos = new ParsePosition(0);
            parsedObj = SubSecondTimeWithUnitFormat.getInstance().parseObject(val, pos);
            // The full string should have been parsed, not just the first
            // numerical characters
            if (pos.getErrorIndex() < 0 && pos.getIndex() == val.length() && parsedObj instanceof Number) {
                return (Number) parsedObj;
            }

            // Try the timestamp formatter
            try {
                return TmfTimestampFormat.getDefaulTimeFormat().parseValue(val);
            } catch (ParseException e) {
                // Nothing to do
            }

            return null;
        }

        @Override
        public boolean test(Object arg0, Object arg1) {
            return Objects.requireNonNull(fCmpFunction.apply(arg0, arg1));
        }

        /**
         * Convert a human-readable string value to its machine representation.
         * For example, duration strings such as "200ms" can be converted to the
         * long value of 200000000. For the MATCHES operator, return a pair that
         * contains the compiled pattern and the parsed value.
         *
         * @param operator
         *            The operator for which the value is prepared
         * @param value
         *            The human-readable string value entered by the user
         * @return The parsed value as a number if available, or the string
         *         itself if no formatter succeeded, or a pair of the compiled
         *         pattern and the parsed value.
         */
        public static @Nullable Object prepareValue(ConditionOperator operator, @Nullable String value) {
            if (value == null) {
                return null;
            }
            Object parsedValue = value;
            // Try to convert to a number
            Number number = toNumber(value);
            if (number != null) {
                parsedValue = number;
            }
            Pattern pattern = null;
            if (operator == ConditionOperator.MATCHES) {
                // Try to compile to a pattern
                try {
                    pattern = Pattern.compile(String.valueOf(value));
                } catch (PatternSyntaxException e) {
                    // Ignore
                }
                if (pattern != null) {
                    return new Pair<>(pattern, parsedValue);
                }
            }
            return parsedValue;
        }
    }

    @Override
    public ITmfFilterTreeNode getEventFilter(ITmfTrace trace) {
        if (fField.equals(IFilterStrings.WILDCARD)) {
            // Make a OR on all aspects
            TmfFilterOrNode orNode = new TmfFilterOrNode(null);
            for (ITmfEventAspect<?> aspect : trace.getEventAspects()) {
                TmfFilterMatchesNode node = new TmfFilterMatchesNode(null);
                node.setEventAspect(aspect);
                node.setRegex(fValue);
                orNode.addChild(node);
            }
            orNode.setNot(getNot());
            return orNode;
        }
        // Find an event aspect corresponding to the field
        ITmfEventAspect<?> filterAspect = null;
        for (ITmfEventAspect<?> aspect : trace.getEventAspects()) {
            if (aspect.getName().equals(fField)) {
                filterAspect = aspect;
                break;
            }
        }
        if (filterAspect == null) {
            // Fallback to a field aspect
            filterAspect = TmfBaseAspects.getContentsAspect().forField(fField);
        }
        TmfFilterAspectNode conditionNode = createConditionNode();
        conditionNode.setEventAspect(filterAspect);

        return conditionNode;
    }

    private TmfFilterAspectNode createConditionNode() {
        switch (fOperator) {
        case IFilterStrings.EQUAL:
            TmfFilterEqualsNode equalsNode = new TmfFilterEqualsNode(null);
            equalsNode.setValue(fValue);
            equalsNode.setNot(getNot());
            return equalsNode;
        case IFilterStrings.NOT_EQUAL:
            TmfFilterEqualsNode notEqualsNode = new TmfFilterEqualsNode(null);
            notEqualsNode.setValue(fValue);
            notEqualsNode.setNot(!getNot());
            return notEqualsNode;
        case IFilterStrings.MATCHES:
            TmfFilterMatchesNode matchesNode = new TmfFilterMatchesNode(null);
            matchesNode.setRegex(fValue);
            matchesNode.setNot(getNot());
            return matchesNode;
        case IFilterStrings.CONTAINS:
            TmfFilterContainsNode containsNode = new TmfFilterContainsNode(null);
            containsNode.setValue(fValue);
            containsNode.setNot(getNot());
            return containsNode;
        case IFilterStrings.PRESENT:
            TmfFilterMatchesNode presentNode = new TmfFilterMatchesNode(null);
            presentNode.setRegex(".*"); //$NON-NLS-1$
            presentNode.setNot(getNot());
            return presentNode;
        case IFilterStrings.GT:
            TmfFilterCompareNode gtNode = new TmfFilterCompareNode(null);
            gtNode.setResult(1);
            gtNode.setValue(fValue);
            gtNode.setNot(getNot());
            return gtNode;
        case IFilterStrings.LT:
            TmfFilterCompareNode ltNode = new TmfFilterCompareNode(null);
            ltNode.setResult(-1);
            ltNode.setValue(fValue);
            ltNode.setNot(getNot());
            return ltNode;
        default:
            throw new IllegalArgumentException("FilterSimpleExpression: invalid comparison operator."); //$NON-NLS-1$
        }
    }

    /**
     * Get whether this Cu expression is a negation
     *
     * @return <code>true</code> if the expression is a negation
     */
    protected boolean getNot() {
        return false;
    }

}
