/*
 * 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.server.core.uri.queryoption.expression;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
import org.apache.olingo.server.api.uri.queryoption.expression.Method;
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
import org.apache.olingo.server.api.uri.queryoption.expression.TypeLiteral;
import org.apache.olingo.server.core.ODataImpl;

public class MethodImpl implements Method {

  private final MethodKind method;
  private final List<Expression> parameters;

  public MethodImpl(final MethodKind method, final List<Expression> parameters) {
    this.method = method;
    this.parameters = parameters;
  }

  @Override
  public MethodKind getMethod() {
    return method;
  }

  public EdmType getType() {
    EdmPrimitiveTypeKind kind = null;
    switch (method) {
    case CONTAINS:
    case STARTSWITH:
    case ENDSWITH:
    case SUBSTRINGOF:
      kind = EdmPrimitiveTypeKind.Boolean;
      break;
    case LENGTH:
    case INDEXOF:
      kind = EdmPrimitiveTypeKind.Int32;
      break;
    case SUBSTRING:
    case TOLOWER:
    case TOUPPER:
    case TRIM:
    case CONCAT:
      kind = EdmPrimitiveTypeKind.String;
      break;
    case YEAR:
    case MONTH:
    case DAY:
    case HOUR:
    case MINUTE:
    case SECOND:
      kind = EdmPrimitiveTypeKind.Int32;
      break;
    case FRACTIONALSECONDS:
    case TOTALSECONDS:
      kind = EdmPrimitiveTypeKind.Decimal;
      break;
    case DATE:
      kind = EdmPrimitiveTypeKind.Date;
      break;
    case TIME:
      kind = EdmPrimitiveTypeKind.TimeOfDay;
      break;
    case TOTALOFFSETMINUTES:
      kind = EdmPrimitiveTypeKind.Int32;
      break;
    case MINDATETIME:
    case MAXDATETIME:
    case NOW:
      kind = EdmPrimitiveTypeKind.DateTimeOffset;
      break;
    case ROUND:
    case FLOOR:
    case CEILING:
      // Needs to be refined if Decimal must be distinguished from Double.
      kind = EdmPrimitiveTypeKind.Double;
      break;
    case GEODISTANCE:
    case GEOLENGTH:
      kind = EdmPrimitiveTypeKind.Double;
      break;
    case GEOINTERSECTS:
      kind = EdmPrimitiveTypeKind.Boolean;
      break;
    case CAST:
      return ((TypeLiteral) parameters.get(parameters.size() - 1)).getType();
    case ISOF:
      kind = EdmPrimitiveTypeKind.Boolean;
      break;
    }
    return new ODataImpl().createPrimitiveTypeInstance(kind);
  }

  @Override
  public List<Expression> getParameters() {
    return parameters == null ?
        Collections.<Expression> emptyList() :
        Collections.unmodifiableList(parameters);
  }

  @Override
  public <T> T accept(final ExpressionVisitor<T> visitor) throws ExpressionVisitException, ODataApplicationException {
    List<T> userParameters = new ArrayList<>();
    if (parameters != null) {
      for (final Expression parameter : parameters) {
        userParameters.add(parameter.accept(visitor));
      }
    }
    return visitor.visitMethodCall(method, userParameters);
  }

  @Override
  public String toString() {
    return "{" + method + " " + parameters + "}";
  }
}
