/********************************************************************************
 * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/

package org.eclipse.mdm.businessobjects.control;

import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.eclipse.mdm.api.base.adapter.Attribute;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarBaseVisitor;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarLexer;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.AndExpressionContext;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.AttributeContext;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.ComparatorExpressionContext;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.ListComparatorExpressionContext;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.NotExpressionContext;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.OrExpressionContext;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.UnaryComparatorExpressionContext;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.ValueContext;
import org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.ValuesContext;
import org.eclipse.mdm.businessobjects.utils.ServiceUtils;

import com.google.common.base.Strings;
import com.google.common.primitives.Booleans;
import com.google.common.primitives.Bytes;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;

/**
 * Class for parsing filter strings.
 * 
 * @author Matthias Koller
 *
 */
public class FilterParser {

	private FilterParser() {
	}

	/**
	 * Visitor class to convert the parsed tree into a {@link Filter}.
	 */
	private static final class FilterVisitor extends FilterGrammarBaseVisitor<Filter> {
		private List<EntityType> availableEntityTypes;

		/**
		 * Constructs a new Visitor operating on the given search attributes.
		 * 
		 * @param availableEntityTypes List of {@link EntityType}s to match the parsed
		 *                             attributes against.
		 */
		private FilterVisitor(List<EntityType> availableEntityTypes) {
			this.availableEntityTypes = availableEntityTypes;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.mdm.businessobjects.filter.FilterGrammarBaseVisitor#
		 * visitAndExpression(org.eclipse.mdm.businessobjects.filter.FilterGrammarParser
		 * .AndExpressionContext)
		 */
		@Override
		public Filter visitAndExpression(AndExpressionContext ctx) {
			return Filter.and().merge(visit(ctx.left), visit(ctx.right));
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.mdm.businessobjects.filter.FilterGrammarBaseVisitor#
		 * visitOrExpression(org.eclipse.mdm.businessobjects.filter.FilterGrammarParser.
		 * OrExpressionContext)
		 */
		@Override
		public Filter visitOrExpression(OrExpressionContext ctx) {
			return Filter.or().merge(visit(ctx.left), visit(ctx.right));
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.mdm.businessobjects.filter.FilterGrammarBaseVisitor#
		 * visitNotExpression(org.eclipse.mdm.businessobjects.filter.FilterGrammarParser
		 * .NotExpressionContext)
		 */
		@Override
		public Filter visitNotExpression(NotExpressionContext ctx) {
			return super.visitNotExpression(ctx).invert();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.mdm.businessobjects.filter.FilterGrammarBaseVisitor#
		 * visitComparatorExpression(org.eclipse.mdm.businessobjects.filter.
		 * FilterGrammarParser.ComparatorExpressionContext)
		 */
		@Override
		public Filter visitComparatorExpression(ComparatorExpressionContext ctx) {
			ComparisonOperator operator = getOperator(ctx.op);
			Attribute attribute = getAttribute(ctx.left);
			Object value = createConditionValue(attribute.getValueType(), getValue(ctx.right));

			return Filter.and().add(operator.create(attribute, value));
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.mdm.businessobjects.filter.FilterGrammarBaseVisitor#
		 * visitListComparatorExpression(org.eclipse.mdm.businessobjects.filter.
		 * FilterGrammarParser.ListComparatorExpressionContext)
		 */
		@Override
		public Filter visitListComparatorExpression(ListComparatorExpressionContext ctx) {
			ComparisonOperator operator = getOperator(ctx.op);
			Attribute attribute = getAttribute(ctx.left);
			Object value = createConditionValues(attribute.getValueType(), getValues(ctx.right));

			return Filter.and().add(operator.create(attribute, value));
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.mdm.businessobjects.filter.FilterGrammarBaseVisitor#
		 * visitUnaryComparatorExpression(org.eclipse.mdm.businessobjects.filter.
		 * FilterGrammarParser.UnaryComparatorExpressionContext)
		 */
		@Override
		public Filter visitUnaryComparatorExpression(UnaryComparatorExpressionContext ctx) {
			ComparisonOperator operator = getOperator(ctx.op);
			Attribute attribute = getAttribute(ctx.left);
			Object value = createConditionValue(attribute.getValueType(), null);

			return Filter.and().add(operator.create(attribute, value));
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.antlr.v4.runtime.tree.AbstractParseTreeVisitor#aggregateResult(java.lang.
		 * Object, java.lang.Object)
		 */
		@Override
		protected Filter aggregateResult(Filter aggregate, Filter nextResult) {
			if (nextResult == null) {
				return aggregate;
			}
			return super.aggregateResult(aggregate, nextResult);
		}

		/**
		 * Extract a string from the given {@link ValueContext}. Basically this methods
		 * returns a string representation of the value without enclosing quotes (if
		 * there were any).
		 * 
		 * @param ctx {@link ValueContext} containing the parsed value.
		 * @return string representation of the value given by {@link ValueContext}
		 */
		private String getValue(ValueContext ctx) {

			TerminalNode typeNode = (TerminalNode) ctx.getChild(0);
			switch (typeNode.getSymbol().getType()) {
			case FilterGrammarLexer.STRINGLITERAL:
				String str = ctx.STRINGLITERAL().getText();
				if (!str.isEmpty() && str.charAt(0) == '\'') {
					// replace leading and trailing ' and unescape '
					return ctx.STRINGLITERAL().getText().replaceAll("(\\A')|('\\z)", "").replaceAll("\\\\'", "'");
				} else if (!str.isEmpty() && str.charAt(0) == '\"') {
					// replace leading and trailing " and unescape "
					return ctx.STRINGLITERAL().getText().replaceAll("(\\A\")|(\"\\z)", "").replaceAll("\\\\\\\"", "\"");
				} else {
					return str;
				}
			case FilterGrammarLexer.DECIMAL:
			case FilterGrammarLexer.LONG:
			case FilterGrammarLexer.BOOL:
				return ctx.getText();
			default:
				throw new RuntimeException("Unsupported Symbol: " + typeNode.getSymbol().getType());
			}
		}

		/**
		 * Extract a list string from the given {@link ValuesContext}. Basically this
		 * methods returns a list of string representations of the values without
		 * enclosing quotes (if there were any).
		 * 
		 * @param ctx {@link ValuesContext} containing the parsed values.
		 * @return string representations of the values given by {@link ValuesContext}
		 */
		private List<String> getValues(ValuesContext ctx) {
			List<String> values = new ArrayList<>();
			for (org.antlr.v4.runtime.tree.ParseTree child : ctx.children) {
				if (child instanceof ValueContext) {
					values.add(getValue((ValueContext) child));
				}
			}
			return values;
		}

		/**
		 * Converts an {@link AttributeContext} into an {@link Attribute} using the list
		 * of available EntityTypes.
		 * 
		 * @param ctx parsed entitytype / attribute
		 * @return the matched {@link Attribute} given by {@link AttributeContext}
		 * @throws IllegalArgumentException if {@link EntityType} or {@link Attribute}
		 *                                  given by <code>ctx</code> cannot be found.
		 */
		private Attribute getAttribute(AttributeContext ctx) {
			String[] name = ctx.getText().split("\\.");
			return availableEntityTypes.stream().filter(e -> ServiceUtils.workaroundForTypeMapping(e).equals(name[0]))
					.findAny()
					.orElseThrow(() -> new IllegalArgumentException("Entity " + name[0] + " not found in data source!"))
					.getAttribute(name[1]);
		}

		/**
		 * Converts a {@link ParserRuleContext} containing a {@link TerminalNode} into a
		 * {@link ComparisonOperator}.
		 * 
		 * @param ctx {@link UnaryComparatorExpressionContext},
		 *            {@link ComparatorExpressionContext} or
		 *            {@link ListComparatorExpressionContext} or
		 * @return converted {@link ComparisonOperator}
		 * @throws IllegalArgumentException if the operator given by <code>ctx</code> is
		 *                                  unknown or cannot be converted.
		 */
		private ComparisonOperator getOperator(ParserRuleContext ctx) {
			TerminalNode typeNode = (TerminalNode) ctx.getChild(0);
			switch (typeNode.getSymbol().getType()) {
			case FilterGrammarLexer.EQUAL:
				return ComparisonOperator.EQUAL;
			case FilterGrammarLexer.NOT_EQUAL:
				return ComparisonOperator.NOT_EQUAL;
			case FilterGrammarLexer.LESS_THAN:
				return ComparisonOperator.LESS_THAN;
			case FilterGrammarLexer.LESS_THAN_OR_EQUAL:
				return ComparisonOperator.LESS_THAN_OR_EQUAL;
			case FilterGrammarLexer.GREATER_THAN:
				return ComparisonOperator.GREATER_THAN;
			case FilterGrammarLexer.GREATER_THAN_OR_EQUAL:
				return ComparisonOperator.GREATER_THAN_OR_EQUAL;
			case FilterGrammarLexer.IN_SET:
				return ComparisonOperator.IN_SET;
			case FilterGrammarLexer.NOT_IN_SET:
				return ComparisonOperator.NOT_IN_SET;
			case FilterGrammarLexer.LIKE:
				return ComparisonOperator.LIKE;
			case FilterGrammarLexer.NOT_LIKE:
				return ComparisonOperator.NOT_LIKE;
			case FilterGrammarLexer.CASE_INSENSITIVE_EQUAL:
				return ComparisonOperator.CASE_INSENSITIVE_EQUAL;
			case FilterGrammarLexer.CASE_INSENSITIVE_NOT_EQUAL:
				return ComparisonOperator.CASE_INSENSITIVE_NOT_EQUAL;
			case FilterGrammarLexer.CASE_INSENSITIVE_LESS_THAN:
				return ComparisonOperator.CASE_INSENSITIVE_LESS_THAN;
			case FilterGrammarLexer.CASE_INSENSITIVE_LESS_THAN_OR_EQUAL:
				return ComparisonOperator.CASE_INSENSITIVE_LESS_THAN_OR_EQUAL;
			case FilterGrammarLexer.CASE_INSENSITIVE_GREATER_THAN:
				return ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN;
			case FilterGrammarLexer.CASE_INSENSITIVE_GREATER_THAN_OR_EQUAL:
				return ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN_OR_EQUAL;
			case FilterGrammarLexer.CASE_INSENSITIVE_IN_SET:
				return ComparisonOperator.CASE_INSENSITIVE_IN_SET;
			case FilterGrammarLexer.CASE_INSENSITIVE_NOT_IN_SET:
				return ComparisonOperator.CASE_INSENSITIVE_NOT_IN_SET;
			case FilterGrammarLexer.CASE_INSENSITIVE_LIKE:
				return ComparisonOperator.CASE_INSENSITIVE_LIKE;
			case FilterGrammarLexer.CASE_INSENSITIVE_NOT_LIKE:
				return ComparisonOperator.CASE_INSENSITIVE_NOT_LIKE;
			case FilterGrammarLexer.IS_NULL:
				return ComparisonOperator.IS_NULL;
			case FilterGrammarLexer.IS_NOT_NULL:
				return ComparisonOperator.IS_NOT_NULL;
			case FilterGrammarLexer.BETWEEN:
				return ComparisonOperator.BETWEEN;
			default:
				throw new IllegalArgumentException(
						"Operator " + typeNode.getSymbol().getType() + " not supported yet!");
			}
		}
	}

	/**
	 * Class to convert a antlr syntax error into a unchecked
	 * ParserCancellationException.
	 */
	private static class ThrowingErrorListener extends BaseErrorListener {

		public static final ThrowingErrorListener INSTANCE = new ThrowingErrorListener();

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.antlr.v4.runtime.BaseErrorListener#syntaxError(org.antlr.v4.runtime.
		 * Recognizer, java.lang.Object, int, int, java.lang.String,
		 * org.antlr.v4.runtime.RecognitionException)
		 */
		@Override
		public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
				String msg, RecognitionException e) throws ParseCancellationException {
			throw new ParseCancellationException("line " + line + ":" + charPositionInLine + " " + msg);
		}
	}

	/**
	 * Parses the given filter string. The filter string must conform to the ANTLR
	 * grammer defined in FilterGrammar.g4.
	 * 
	 * @param possibleEntityTypes The possible {@link EntityType}s /
	 *                            {@link Attribute}s
	 * @param filterString        The filter string to parse.
	 * @return the parsed {@link Filter}
	 * @throws IllegalArgumentExceptionThrown if parsing fails.
	 */
	public static Filter parseFilterString(List<EntityType> possibleEntityTypes, String filterString)
			throws IllegalArgumentException {

		if (Strings.isNullOrEmpty(filterString)) {
			return Filter.and();
		}

		try {
			FilterGrammarLexer lexer = new FilterGrammarLexer(new ANTLRInputStream(filterString));
			lexer.removeErrorListeners();
			lexer.addErrorListener(ThrowingErrorListener.INSTANCE);

			FilterGrammarParser parser = new FilterGrammarParser(new CommonTokenStream(lexer));
			parser.removeErrorListeners();
			parser.addErrorListener(ThrowingErrorListener.INSTANCE);

			return new FilterVisitor(possibleEntityTypes).visit(parser.parse());
		} catch (ParseCancellationException e) {
			throw new IllegalArgumentException(
					"Could not parse filter string '" + filterString + "'. Error: " + e.getMessage(), e);
		}
	}

	/**
	 * Creates the value for the condition from the value given as string.
	 * 
	 * @param valueType     The type that the value should have.
	 * @param valueAsString The value as string.
	 * @return The created value for the condition.
	 * @throws IllegalArgumentException Thrown if the value type is not supported
	 */
	private static Object createConditionValue(ValueType<?> valueType, String valueAsString) {
		Object ret = null;
		if (ValueType.BOOLEAN.equals(valueType)) {
			ret = Boolean.valueOf(valueAsString);
		} else if (ValueType.LONG.equals(valueType)) {
			ret = Long.valueOf(valueAsString);
		} else if (ValueType.STRING.equals(valueType)) {
			ret = valueAsString;
		} else if (ValueType.BYTE.equals(valueType)) {
			ret = Byte.valueOf(valueAsString);
		} else if (ValueType.DOUBLE.equals(valueType)) {
			ret = Double.valueOf(valueAsString);
		} else if (ValueType.FLOAT.equals(valueType)) {
			ret = Float.valueOf(valueAsString);
		} else if (ValueType.INTEGER.equals(valueType)) {
			ret = Integer.valueOf(valueAsString);
		} else if (ValueType.SHORT.equals(valueType)) {
			ret = Short.valueOf(valueAsString);
		} else if (ValueType.DATE.equals(valueType)) {
			try {
				ret = LocalDateTime.parse(valueAsString);
			} catch (DateTimeParseException e) {
				throw new IllegalArgumentException(
						"Unsupported value for date: '" + valueAsString + "'. Expected format: '2007-12-03T10:15:30'");
			}
		} else {
			throw new IllegalArgumentException("Unsupported value type: " + valueType.toString());
		}
		return ret;
	}

	/**
	 * Creates the values for the condition from the values given in the list of
	 * strings.
	 * 
	 * @param valueType      The type that the value should have.
	 * @param valuesAsString The values as a list of string.
	 * @return The created value for the condition.
	 * @throws IllegalArgumentException Thrown if the value type is not supported
	 */
	private static Object createConditionValues(ValueType<?> valueType, List<String> valuesAsStrings) {

		if (ValueType.BOOLEAN.equals(valueType)) {
			List<Boolean> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				list.add(Boolean.valueOf(valueAsString));
			}
			return Booleans.toArray(list);
		} else if (ValueType.LONG.equals(valueType)) {
			List<Long> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				list.add(Long.valueOf(valueAsString));
			}
			return Longs.toArray(list);
		} else if (ValueType.STRING.equals(valueType)) {
			List<String> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				list.add(valueAsString);
			}
			return list.toArray(new String[0]);
		} else if (ValueType.BYTE.equals(valueType)) {
			List<Byte> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				list.add(Byte.valueOf(valueAsString));
			}
			return Bytes.toArray(list);
		} else if (ValueType.DOUBLE.equals(valueType)) {
			List<Double> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				list.add(Double.valueOf(valueAsString));
			}
			return Doubles.toArray(list);
		} else if (ValueType.FLOAT.equals(valueType)) {
			List<Float> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				list.add(Float.valueOf(valueAsString));
			}
			return Floats.toArray(list);
		} else if (ValueType.INTEGER.equals(valueType)) {
			List<Integer> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				list.add(Integer.valueOf(valueAsString));
			}
			return Ints.toArray(list);
		} else if (ValueType.SHORT.equals(valueType)) {
			List<Short> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				list.add(Short.valueOf(valueAsString));
			}
			return Shorts.toArray(list);
		} else if (ValueType.DATE.equals(valueType)) {
			List<LocalDateTime> list = new ArrayList<>();
			for (String valueAsString : valuesAsStrings) {
				try {
					list.add(LocalDateTime.parse(valueAsString));
				} catch (DateTimeParseException e) {
					throw new IllegalArgumentException("Unsupported value for date: '" + valueAsString
							+ "'. Expected format: '2007-12-03T10:15:30'");
				}
			}
			return list.toArray(new LocalDateTime[0]);
		} else {
			throw new IllegalArgumentException("Unsupported value type: " + valueType.toString());
		}
	}
}
