/*******************************************************************************
 * 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.olingo.odata2.jpa.processor.core;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmLiteral;
import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
import org.apache.olingo.odata2.api.edm.EdmMapping;
import org.apache.olingo.odata2.api.edm.EdmProperty;
import org.apache.olingo.odata2.api.edm.EdmSimpleType;
import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
import org.apache.olingo.odata2.api.uri.KeyPredicate;
import org.apache.olingo.odata2.api.uri.expression.BinaryExpression;
import org.apache.olingo.odata2.api.uri.expression.BinaryOperator;
import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
import org.apache.olingo.odata2.api.uri.expression.LiteralExpression;
import org.apache.olingo.odata2.api.uri.expression.MemberExpression;
import org.apache.olingo.odata2.api.uri.expression.MethodExpression;
import org.apache.olingo.odata2.api.uri.expression.MethodOperator;
import org.apache.olingo.odata2.api.uri.expression.OrderByExpression;
import org.apache.olingo.odata2.api.uri.expression.OrderExpression;
import org.apache.olingo.odata2.api.uri.expression.PropertyExpression;
import org.apache.olingo.odata2.api.uri.expression.SortOrder;
import org.apache.olingo.odata2.api.uri.expression.UnaryExpression;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement;

/**
 * This class contains utility methods for parsing the filter expressions built by core library from user OData Query.
 *
 *
 *
 */
public class ODataExpressionParser {

  public static final String EMPTY = ""; //$NON-NLS-1$
  public static final ThreadLocal<Integer> methodFlag = new ThreadLocal<Integer>();

  /**
   * This method returns the parsed where condition corresponding to the filter input in the user query.
   *
   * @param whereExpression
   *
   * @return Parsed where condition String
   * @throws ODataException
   */

  public static String parseToJPAWhereExpression(final CommonExpression whereExpression, final String tableAlias)
      throws ODataException {
    switch (whereExpression.getKind()) {
    case UNARY:
      final UnaryExpression unaryExpression = (UnaryExpression) whereExpression;
      final String operand = parseToJPAWhereExpression(unaryExpression.getOperand(), tableAlias);

      switch (unaryExpression.getOperator()) {
      case NOT:
        return JPQLStatement.Operator.NOT + JPQLStatement.DELIMITER.PARENTHESIS_LEFT + operand
            + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT; //$NON-NLS-1$ //$NON-NLS-2$
      case MINUS:
        if (operand.startsWith("-")) {
          return operand.substring(1);
        } else {
          return "-" + operand; //$NON-NLS-1$
        }
      default:
        throw new ODataNotImplementedException();
      }

    case FILTER:
      return parseToJPAWhereExpression(((FilterExpression) whereExpression).getExpression(), tableAlias);
    case BINARY:
      final BinaryExpression binaryExpression = (BinaryExpression) whereExpression;
      MethodOperator operator = null;
      if (binaryExpression.getLeftOperand().getKind() == ExpressionKind.METHOD) {
        operator = ((MethodExpression) binaryExpression.getLeftOperand()).getMethod();
      }
      if (operator != null && ((binaryExpression.getOperator() == BinaryOperator.EQ) ||
          (binaryExpression.getOperator() == BinaryOperator.NE))) {
        if (operator == MethodOperator.SUBSTRINGOF) {
          methodFlag.set(1);
        }
      }
      final String left = parseToJPAWhereExpression(binaryExpression.getLeftOperand(), tableAlias);
      final String right = parseToJPAWhereExpression(binaryExpression.getRightOperand(), tableAlias);

      // Special handling for STARTSWITH and ENDSWITH method expression
      if (operator != null && (operator == MethodOperator.STARTSWITH || operator == MethodOperator.ENDSWITH)) {
        if (!binaryExpression.getOperator().equals(BinaryOperator.EQ)) {
          throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.OPERATOR_EQ_NE_MISSING
              .addContent(binaryExpression.getOperator().toString()), null);
        } else if (right.equals("false")) {
          return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left.replaceFirst("LIKE", "NOT LIKE")
              + JPQLStatement.DELIMITER.SPACE
              + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
        } else {
          return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left
              + JPQLStatement.DELIMITER.SPACE
              + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
        }
      }
      switch (binaryExpression.getOperator()) {
      case AND:
        return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
            + JPQLStatement.Operator.AND + JPQLStatement.DELIMITER.SPACE
            + right + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
      case OR:
        return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
            + JPQLStatement.Operator.OR + JPQLStatement.DELIMITER.SPACE + right
            + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
      case EQ:
        return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
            + (!"null".equals(right) ? JPQLStatement.Operator.EQ : "IS") + JPQLStatement.DELIMITER.SPACE + right
            + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
      case NE:
        return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
            + (!"null".equals(right) ? 
            	  JPQLStatement.Operator.NE :
            	  "IS" + JPQLStatement.DELIMITER.SPACE + JPQLStatement.Operator.NOT)
            + JPQLStatement.DELIMITER.SPACE + right
            + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
      case LT:
        return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
            + JPQLStatement.Operator.LT + JPQLStatement.DELIMITER.SPACE + right
            + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
      case LE:
        return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
            + JPQLStatement.Operator.LE + JPQLStatement.DELIMITER.SPACE + right
            + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
      case GT:
        return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
            + JPQLStatement.Operator.GT + JPQLStatement.DELIMITER.SPACE + right
            + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
      case GE:
        return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
            + JPQLStatement.Operator.GE + JPQLStatement.DELIMITER.SPACE + right
            + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
      case PROPERTY_ACCESS:
        throw new ODataNotImplementedException();
      default:
        throw new ODataNotImplementedException();

      }

    case PROPERTY:
      String returnStr = tableAlias + JPQLStatement.DELIMITER.PERIOD
          + getPropertyName(whereExpression);
      return returnStr;

    case MEMBER:
      String memberExpStr = EMPTY;
      int i = 0;
      MemberExpression member = null;
      CommonExpression tempExp = whereExpression;
      while (tempExp != null && tempExp.getKind() == ExpressionKind.MEMBER) {
        member = (MemberExpression) tempExp;
        if (i > 0) {
          memberExpStr = JPQLStatement.DELIMITER.PERIOD + memberExpStr;
        }
        i++;
        memberExpStr = getPropertyName(member.getProperty()) + memberExpStr;
        tempExp = member.getPath();
      }
      memberExpStr =
          getPropertyName(tempExp) + JPQLStatement.DELIMITER.PERIOD + memberExpStr;
      return tableAlias + JPQLStatement.DELIMITER.PERIOD + memberExpStr;

    case LITERAL:
      final LiteralExpression literal = (LiteralExpression) whereExpression;
      final EdmSimpleType literalType = (EdmSimpleType) literal.getEdmType();
      EdmLiteral uriLiteral = EdmSimpleTypeKind.parseUriLiteral(literal.getUriLiteral());
      return evaluateComparingExpression(uriLiteral.getLiteral(), literalType);

    case METHOD:
      final MethodExpression methodExpression = (MethodExpression) whereExpression;
      String first = parseToJPAWhereExpression(methodExpression.getParameters().get(0), tableAlias);
      String second =
          methodExpression.getParameterCount() > 1 ? parseToJPAWhereExpression(methodExpression.getParameters().get(1),
              tableAlias) : null;
      String third =
          methodExpression.getParameterCount() > 2 ? parseToJPAWhereExpression(methodExpression.getParameters().get(2),
              tableAlias) : null;

      switch (methodExpression.getMethod()) {
      case SUBSTRING:
        third = third != null ? ", " + third : "";
        return String.format("SUBSTRING(%s, %s + 1 %s)", first, second, third);
      case SUBSTRINGOF:
        if (methodFlag.get() != null && methodFlag.get() == 1) {
          methodFlag.set(null);
          return String.format("(CASE WHEN (%s LIKE CONCAT('%%',CONCAT(%s,'%%'))) THEN TRUE ELSE FALSE END)",
              second, first);
        } else {
          return String.format("(CASE WHEN (%s LIKE CONCAT('%%',CONCAT(%s,'%%'))) THEN TRUE ELSE FALSE END) = true",
              second, first);
        }
      case TOLOWER:
        return String.format("LOWER(%s)", first);
      case STARTSWITH:
        // second = second.substring(1, second.length() - 1);
        return String.format("%s LIKE CONCAT(%s,'%%')", first, second);
      case ENDSWITH:
        // second = second.substring(1, second.length() - 1);
        return String.format("%s LIKE CONCAT('%%',%s)", first, second);
      default:
        throw new ODataNotImplementedException();
      }

    default:
      throw new ODataNotImplementedException();
    }
  }

  /**
   * This method parses the select clause
   *
   * @param tableAlias
   * @param selectedFields
   * @return a select expression
   */
  public static String parseToJPASelectExpression(final String tableAlias, final ArrayList<String> selectedFields) {

    if ((selectedFields == null) || (selectedFields.size() == 0)) {
      return tableAlias;
    }

    String selectClause = EMPTY;
    Iterator<String> itr = selectedFields.iterator();
    int count = 0;

    while (itr.hasNext()) {
      selectClause = selectClause + tableAlias + JPQLStatement.DELIMITER.PERIOD + itr.next();
      count++;

      if (count < selectedFields.size()) {
        selectClause = selectClause + JPQLStatement.DELIMITER.COMMA + JPQLStatement.DELIMITER.SPACE;
      }
    }
    return selectClause;
  }

  /**
   * This method parses the order by condition in the query.
   *
   * @param orderByExpression
   * @return a map of JPA attributes and their sort order
   * @throws ODataJPARuntimeException
   */
  public static String parseToJPAOrderByExpression(final OrderByExpression orderByExpression,
      final String tableAlias) throws ODataJPARuntimeException {
    String jpqlOrderByExpression = "";
    if (orderByExpression != null && orderByExpression.getOrders() != null) {
      List<OrderExpression> orderBys = orderByExpression.getOrders();
      String orderByField = null;
      String orderByDirection = null;
      for (OrderExpression orderBy : orderBys) {

        try {
          if (orderBy.getExpression().getKind() == ExpressionKind.MEMBER) {
            orderByField = parseToJPAWhereExpression(orderBy.getExpression(), tableAlias);
          } else {
            orderByField = tableAlias + JPQLStatement.DELIMITER.PERIOD + getPropertyName(orderBy.getExpression());
          }
          orderByDirection = (orderBy.getSortOrder() == SortOrder.asc) ? EMPTY :
              JPQLStatement.DELIMITER.SPACE + "DESC"; //$NON-NLS-1$
          jpqlOrderByExpression += orderByField + orderByDirection + " , ";
        } catch (EdmException e) {
          throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
        } catch (ODataException e) {
          throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
        }
      }
    }
    return normalizeOrderByExpression(jpqlOrderByExpression);
  }

  private static String normalizeOrderByExpression(final String jpqlOrderByExpression) {
    if (jpqlOrderByExpression != "") {
      return jpqlOrderByExpression.substring(0, jpqlOrderByExpression.length() - 3);
    } else {
      return jpqlOrderByExpression;
    }
  }

  /**
   * This method evaluated the where expression for read of an entity based on the keys specified in the query.
   *
   * @param keyPredicates
   * @return the evaluated where expression
   */

  public static String parseKeyPredicates(final List<KeyPredicate> keyPredicates, final String tableAlias)
      throws ODataJPARuntimeException {
    String literal = null;
    String propertyName = null;
    EdmSimpleType edmSimpleType = null;
    StringBuilder keyFilters = new StringBuilder();
    int i = 0;
    for (KeyPredicate keyPredicate : keyPredicates) {
      if (i > 0) {
        keyFilters.append(JPQLStatement.DELIMITER.SPACE + JPQLStatement.Operator.AND + JPQLStatement.DELIMITER.SPACE);
      }
      i++;
      literal = keyPredicate.getLiteral();
      try {
        propertyName = keyPredicate.getProperty().getMapping().getInternalName();
        edmSimpleType = (EdmSimpleType) keyPredicate.getProperty().getType();
      } catch (EdmException e) {
        throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
      }

      literal = evaluateComparingExpression(literal, edmSimpleType);

      if (edmSimpleType == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
          || edmSimpleType == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()) {
        literal = literal.substring(literal.indexOf('\''), literal.indexOf('}'));
      }

      keyFilters.append(tableAlias + JPQLStatement.DELIMITER.PERIOD + propertyName + JPQLStatement.DELIMITER.SPACE
          + JPQLStatement.Operator.EQ + JPQLStatement.DELIMITER.SPACE + literal);
    }
    if (keyFilters.length() > 0) {
      return keyFilters.toString();
    } else {
      return null;
    }
  }

  public static String parseKeyPropertiesToJPAOrderByExpression(
      final List<EdmProperty> edmPropertylist, final String tableAlias) throws ODataJPARuntimeException {
    String propertyName = null;
    String orderExpression = "";
    if (edmPropertylist == null) {
      return orderExpression;
    }
    for (EdmProperty edmProperty : edmPropertylist) {
      try {
        EdmMapping mapping = edmProperty.getMapping();
        if (mapping != null && mapping.getInternalName() != null) {
          propertyName = mapping.getInternalName();// For embedded/complex keys
        } else {
          propertyName = edmProperty.getName();
        }
      } catch (EdmException e) {
        throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
      }
      orderExpression += tableAlias + JPQLStatement.DELIMITER.PERIOD + propertyName + " , ";
    }
    return normalizeOrderByExpression(orderExpression);
  }

  /**
   * This method evaluates the expression based on the type instance. Used for adding escape characters where necessary.
   *
   * @param uriLiteral
   * @param edmSimpleType
   * @return the evaluated expression
   * @throws ODataJPARuntimeException
   */
  private static String evaluateComparingExpression(String uriLiteral, final EdmSimpleType edmSimpleType)
      throws ODataJPARuntimeException {

    if (EdmSimpleTypeKind.String.getEdmSimpleTypeInstance().isCompatible(edmSimpleType)
        || EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance().isCompatible(edmSimpleType)) {
      uriLiteral = uriLiteral.replaceAll("'", "''");
      uriLiteral = "'" + uriLiteral + "'"; //$NON-NLS-1$	//$NON-NLS-2$
    } else if (EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance().isCompatible(edmSimpleType)
        || EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance().isCompatible(edmSimpleType)) {
      try {
        Calendar datetime =
            (Calendar) edmSimpleType.valueOfString(uriLiteral, EdmLiteralKind.DEFAULT, null, edmSimpleType
                .getDefaultType());

        String year = String.format("%04d", datetime.get(Calendar.YEAR));
        String month = String.format("%02d", datetime.get(Calendar.MONTH) + 1);
        String day = String.format("%02d", datetime.get(Calendar.DAY_OF_MONTH));
        String hour = String.format("%02d", datetime.get(Calendar.HOUR_OF_DAY));
        String min = String.format("%02d", datetime.get(Calendar.MINUTE));
        String sec = String.format("%02d", datetime.get(Calendar.SECOND));

        uriLiteral =
            JPQLStatement.DELIMITER.LEFT_BRACE + JPQLStatement.KEYWORD.TIMESTAMP + JPQLStatement.DELIMITER.SPACE + "\'"
                + year + JPQLStatement.DELIMITER.HYPHEN + month + JPQLStatement.DELIMITER.HYPHEN + day
                + JPQLStatement.DELIMITER.SPACE + hour + JPQLStatement.DELIMITER.COLON + min
                + JPQLStatement.DELIMITER.COLON + sec + JPQLStatement.KEYWORD.OFFSET + "\'"
                + JPQLStatement.DELIMITER.RIGHT_BRACE;

      } catch (EdmSimpleTypeException e) {
        throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
      }

    } else if (EdmSimpleTypeKind.Time.getEdmSimpleTypeInstance().isCompatible(edmSimpleType)) {
      try {
        Calendar time =
            (Calendar) edmSimpleType.valueOfString(uriLiteral, EdmLiteralKind.DEFAULT, null, edmSimpleType
                .getDefaultType());

        String hourValue = String.format("%02d", time.get(Calendar.HOUR_OF_DAY));
        String minValue = String.format("%02d", time.get(Calendar.MINUTE));
        String secValue = String.format("%02d", time.get(Calendar.SECOND));

        uriLiteral =
            "\'" + hourValue + JPQLStatement.DELIMITER.COLON + minValue + JPQLStatement.DELIMITER.COLON + secValue
                + "\'";
      } catch (EdmSimpleTypeException e) {
        throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
      }

    } else if (Long.class.equals(edmSimpleType.getDefaultType())) {
      uriLiteral = uriLiteral + JPQLStatement.DELIMITER.LONG; //$NON-NLS-1$
    }
    return uriLiteral;
  }

  private static String getPropertyName(final CommonExpression whereExpression) throws EdmException {
    EdmProperty property = ((EdmProperty) ((PropertyExpression) whereExpression).getEdmProperty());
    EdmMapping mapping = property.getMapping();
    String name = mapping != null ? mapping.getInternalName() : property.getName();
    return name;
  }
}
