/*
 * Copyright (c) 2010-2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Christian W. Damus (CEA LIST) - Additional OCL operations for efficient queries
 */
package org.eclipse.emf.cdo.server.ocl;

import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionCacheAdder;
import org.eclipse.emf.cdo.common.revision.CDORevisionProvider;
import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
import org.eclipse.emf.cdo.server.CDOServerUtil;
import org.eclipse.emf.cdo.server.IQueryContext;
import org.eclipse.emf.cdo.server.IQueryHandler;
import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetDataRevisionProvider;
import org.eclipse.emf.cdo.spi.server.QueryHandlerFactory;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.factory.ProductCreationException;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticException;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;

import org.eclipse.ocl.Environment;
import org.eclipse.ocl.EvaluationEnvironment;
import org.eclipse.ocl.OCL;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.Query;
import org.eclipse.ocl.ecore.BooleanLiteralExp;
import org.eclipse.ocl.ecore.Constraint;
import org.eclipse.ocl.ecore.EcoreEnvironmentFactory;
import org.eclipse.ocl.ecore.EcoreFactory;
import org.eclipse.ocl.ecore.EnumLiteralExp;
import org.eclipse.ocl.ecore.IntegerLiteralExp;
import org.eclipse.ocl.ecore.RealLiteralExp;
import org.eclipse.ocl.ecore.StringLiteralExp;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.expressions.Variable;
import org.eclipse.ocl.helper.OCLHelper;
import org.eclipse.ocl.options.ParsingOptions;
import org.eclipse.ocl.types.OCLStandardLibrary;
import org.eclipse.ocl.util.ProblemAware;
import org.eclipse.ocl.util.Tuple;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * A {@link IQueryHandler query handler} that evaluates OCL query expressions.
 *
 * @author Eike Stepper
 */
public class OCLQueryHandler implements IQueryHandler
{
  public static final String LANGUAGE_NAME = "ocl"; //$NON-NLS-1$

  /**
   * @since 4.1
   */
  public static final String LAZY_EXTENTS_PARAMETER = "cdoLazyExtents";

  /**
   * Query parameter indicating the {@link EClass} to set as the implicit root class of the type
   * hierarchy.  The default is {@code null}.
   *
   * @since 4.2
   */
  public static final String IMPLICIT_ROOT_CLASS_PARAMETER = "cdoImplicitRootClass";

  private static final Set<String> SERVER_QUERY_PARAMETERS = Collections.unmodifiableSet(
      new java.util.HashSet<String>(Arrays.asList(LAZY_EXTENTS_PARAMETER, IMPLICIT_ROOT_CLASS_PARAMETER)));

  private static final EcoreFactory FACTORY = EcoreFactory.eINSTANCE;

  private boolean lazyExtents = true;

  private EClass implicitRootClass;

  public OCLQueryHandler()
  {
  }

  public void executeQuery(CDOQueryInfo info, IQueryContext context)
  {
    CDOExtentMap extentMap = null;

    try
    {
      readParameters(info.getParameters());

      CDORevisionProvider revisionProvider = context.getView();
      CDOChangeSetData changeSetData = info.getChangeSetData();
      if (changeSetData != null)
      {
        revisionProvider = new CDOChangeSetDataRevisionProvider(revisionProvider, changeSetData);
      }

      CDOView view = CDOServerUtil.openView(context.getView().getSession(), context, revisionProvider);
      extentMap = createExtentMap(view, changeSetData, context);
      OCL<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> ocl = createOCL(view, extentMap);

      ContextParameter contextParameter = getContextParameter(info, view);
      Query<EClassifier, EClass, EObject> query = createQuery(view, info, contextParameter, ocl);

      Object result = evaluate(query, contextParameter.getObject());
      if (result == ocl.getEnvironment().getOCLStandardLibrary().getInvalid())
      {
        throw new Exception(
            "OCL query evaluated to 'invalid'. Run with '-Dorg.eclipse.ocl.debug=true' and visit the log for failure details.");
      }

      if (result instanceof Collection<?>)
      {
        for (Object element : (Collection<?>)result)
        {
          if (!addResult(element, context, view))
          {
            break;
          }
        }
      }
      else
      {
        addResult(result, context, view);
      }
    }
    catch (Exception ex)
    {
      throw WrappedException.wrap(ex, "Problem executing OCL query: " + info.getQueryString());
    }
    finally
    {
      if (extentMap != null)
      {
        extentMap.cancel();
      }
    }
  }

  protected boolean addResult(Object result, IQueryContext context, CDOView view)
  {
    result = convertResult(result, view);
    return context.addResult(result);
  }

  protected CDORevision getRevision(EObject object, CDOView view)
  {
    return FSMUtil.adapt(object, view).cdoRevision();
  }

  protected Object evaluate(Query<EClassifier, EClass, EObject> query, EObject object)
  {
    if (object == null)
    {
      return query.evaluate();
    }

    return query.evaluate(object);
  }

  protected CDOExtentMap createExtentMap(CDOView view, CDOChangeSetData changeSetData, IQueryContext context)
  {
    CDOExtentCreator creator = createsLazyExtents() ? new CDOExtentCreator.Lazy(view) : new CDOExtentCreator(view);
    creator.setChangeSetData(changeSetData);
    creator.setRevisionCacheAdder((CDORevisionCacheAdder)context.getView().getRepository().getRevisionManager());
    return new CDOExtentMap(creator);
  }

  protected boolean createsLazyExtents()
  {
    return lazyExtents;
  }

  /**
   * @since 4.2
   */
  protected OCL<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> createOCL(CDOView view,
      CDOExtentMap extentMap)
  {
    EcoreEnvironmentFactory envFactory = new CDOEnvironmentFactory(view.getSession().getPackageRegistry());

    OCL<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> ocl = OCL.newInstance(envFactory);
    CDOAdditionalOperation.registerOperations((CDOEnvironment)ocl.getEnvironment());
    ocl.setExtentMap(extentMap);
    return ocl;
  }

  /**
   * @since 4.2
   */
  protected Query<EClassifier, EClass, EObject> createQuery(CDOView view, CDOQueryInfo info,
      ContextParameter contextParameter, OCL<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> ocl)
          throws ParserException, DiagnosticException
  {
    Map<String, Object> parameters = new HashMap<String, Object>(info.getParameters());
    initEnvironment(ocl.getEnvironment(), view.getSession().getPackageRegistry(), parameters);

    OCLHelper<EClassifier, ?, ?, Constraint> helper = ocl.createOCLHelper();
    helper.setContext(contextParameter.getClassifier());

    OCLExpression<EClassifier> expr = helper.createQuery(info.getQueryString());
    Query<EClassifier, EClass, EObject> query = ocl.createQuery(expr);
    if (query instanceof ProblemAware)
    {
      ProblemAware problemAware = (ProblemAware)query;
      Diagnostic problems = problemAware.getProblems();
      if (problems != null)
      {
        throw new DiagnosticException(problems);
      }
    }

    setOCLQueryParameters(parameters, query);
    return query;
  }

  /**
   * @deprecated As of 4.2 no longer supported.
   */
  @Deprecated
  protected EClassifier getArbitraryContextClassifier(CDOPackageRegistry packageRegistry)
  {
    return ContextParameter.getArbitraryContextClassifier(packageRegistry);
  }

  protected void initEnvironment(
      Environment<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> environment,
      CDOPackageRegistry packageRegistry, Map<String, Object> parameters)
  {

    // initialize parsing options
    EClass implicitRootClass = getImplicitRootClass();
    if (implicitRootClass != null)
    {
      ParsingOptions.setOption(environment, ParsingOptions.implicitRootClass(environment), implicitRootClass);
    }

    // create variables for query parameters that should be passed through to the OCL query expression
    OCLStandardLibrary<EClassifier> stdLib = environment.getOCLStandardLibrary();
    for (Entry<String, Object> parameter : parameters.entrySet())
    {
      String name = parameter.getKey();
      if (isOCLQueryParameter(name))
      {
        Object value = parameter.getValue();

        OCLExpression<EClassifier> initExpression = createInitExpression(stdLib, packageRegistry, value);

        Variable<EClassifier, ?> variable = FACTORY.createVariable();
        variable.setName(name);
        variable.setType(initExpression.getType());
        variable.setInitExpression(initExpression);

        addEnvironmentVariable(environment, variable);
      }
    }
  }

  /**
   * @since 4.2
   */
  protected EClass getImplicitRootClass()
  {
    return implicitRootClass;
  }

  protected OCLExpression<EClassifier> createInitExpression(OCLStandardLibrary<EClassifier> stdLib,
      CDOPackageRegistry packageRegistry, Object value)
  {
    if (value instanceof String)
    {
      String v = (String)value;
      StringLiteralExp literal = FACTORY.createStringLiteralExp();
      literal.setType(stdLib.getString());
      literal.setStringSymbol(v);
      return literal;
    }

    if (value instanceof Boolean)
    {
      Boolean v = (Boolean)value;
      BooleanLiteralExp literal = FACTORY.createBooleanLiteralExp();
      literal.setType(stdLib.getBoolean());
      literal.setBooleanSymbol(v);
      return literal;
    }

    Integer integerValue = getInteger(value);
    if (integerValue != null)
    {
      IntegerLiteralExp literal = FACTORY.createIntegerLiteralExp();
      literal.setType(stdLib.getInteger());
      literal.setIntegerSymbol(integerValue);
      return literal;
    }

    Double doubleValue = getDouble(value);
    if (doubleValue != null)
    {
      RealLiteralExp literal = FACTORY.createRealLiteralExp();
      literal.setType(stdLib.getReal());
      literal.setRealSymbol(doubleValue);
      return literal;
    }

    if (value instanceof Enumerator)
    {
      Enumerator v = (Enumerator)value;
      String name = v.getName();

      EEnumLiteral eEnumLiteral = packageRegistry.getEnumLiteralFor(v);
      if (eEnumLiteral == null)
      {
        throw new IllegalArgumentException("Enum literal not found: " + name);
      }

      EnumLiteralExp literal = FACTORY.createEnumLiteralExp();
      literal.setType(eEnumLiteral.getEEnum());
      literal.setReferredEnumLiteral(eEnumLiteral);
      return literal;
    }

    throw new IllegalArgumentException("Unrecognized parameter type: " + value.getClass().getName());
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  protected void addEnvironmentVariable(
      Environment<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> environment,
      Variable<EClassifier, ?> variable)
  {
    environment.addElement(variable.getName(), (Variable)variable, true);
  }

  /**
   * @since 4.2
   */
  protected ContextParameter getContextParameter(CDOQueryInfo info, CDOView view)
  {
    return new ContextParameter(view, info);
  }

  /**
   * @since 4.2
   */
  protected void readParameters(Map<String, ?> queryParameters)
  {
    lazyExtents = readParameter(queryParameters, LAZY_EXTENTS_PARAMETER, lazyExtents);
    implicitRootClass = readParameter(queryParameters, IMPLICIT_ROOT_CLASS_PARAMETER, EClass.class, implicitRootClass);
  }

  /**
   * @since 4.2
   */
  protected boolean readParameter(Map<String, ?> queryParameters, String name, boolean defaultValue)
  {
    return readParameter(queryParameters, name, Boolean.class, defaultValue);
  }

  /**
   * @since 4.2
   */
  protected <T> T readParameter(Map<String, ?> queryParameters, String name, Class<T> type, T defaultValue)
  {
    T result = defaultValue;

    Object o = queryParameters.get(name);
    if (o != null)
    {
      try
      {
        result = type.cast(o);
      }
      catch (ClassCastException ex)
      {
        throw new IllegalArgumentException("Parameter " + name + " must be a " + type.getSimpleName() + " but it is a "
            + o + " class " + o.getClass().getName(), ex);
      }
    }

    return result;
  }

  /**
   * @since 4.2
   */
  protected void setOCLQueryParameters(Map<String, Object> parameters, Query<EClassifier, EClass, EObject> query)
  {
    EvaluationEnvironment<EClassifier, ?, ?, EClass, EObject> evalEnv = query.getEvaluationEnvironment();
    for (Entry<String, Object> parameter : parameters.entrySet())
    {
      String key = parameter.getKey();

      if (isOCLQueryParameter(key))
      {
        Object value = parameter.getValue();
        evalEnv.add(key, value);
      }
    }
  }

  /**
   * @since 4.2
   */
  protected boolean isOCLQueryParameter(String name)
  {
    return !SERVER_QUERY_PARAMETERS.contains(name);
  }

  private Integer getInteger(Object value)
  {
    if (value instanceof Integer)
    {
      return (Integer)value;
    }

    if (value instanceof Short)
    {
      return (int)(Short)value;
    }

    if (value instanceof Byte)
    {
      return (int)(Byte)value;
    }

    return null;
  }

  private Double getDouble(Object value)
  {
    if (value instanceof Double)
    {
      return (Double)value;
    }

    if (value instanceof Float)
    {
      return (double)(Float)value;
    }

    return null;
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  private Object convertResult(Object result, CDOView view)
  {
    if (result instanceof EObject)
    {
      return getRevision((EObject)result, view);
    }

    if (result instanceof Tuple)
    {
      Tuple tuple = (Tuple)result;
      EList properties = tuple.getTupleType().oclProperties();
      Object[] array = new Object[properties.size()];
      for (int i = 0; i < array.length; ++i)
      {
        array[i] = convertResult(tuple.getValue(properties.get(i)), view);
      }

      return array;
    }

    return result;
  }

  public static void prepareContainer(IManagedContainer container)
  {
    container.registerFactory(new Factory());
  }

  /**
   * Creates {@link OCLQueryHandler} instances.
   *
   * @author Eike Stepper
   */
  public static class Factory extends QueryHandlerFactory
  {
    public Factory()
    {
      super(LANGUAGE_NAME);
    }

    @Override
    public OCLQueryHandler create(String description) throws ProductCreationException
    {
      return new OCLQueryHandler();
    }
  }

  /**
   * An abstraction of the {@link EClassifier classifier} and/or {@link EObject obejct} of an OCL query context parameter.
   *
   * @author Eike Stepper
   * @since 4.2
   */
  protected static final class ContextParameter
  {
    private final EClassifier classifier;

    private final EObject object;

    public ContextParameter(CDOView view, CDOQueryInfo info)
    {
      Object contextParameter = info.getContext();
      if (contextParameter instanceof CDOID)
      {
        CDOID id = (CDOID)contextParameter;
        if (id.isNull())
        {
          CDOPackageRegistry packageRegistry = view.getSession().getPackageRegistry();
          classifier = getArbitraryContextClassifier(packageRegistry);
          object = null;
        }
        else
        {
          InternalCDOObject cdoObject = (InternalCDOObject)view.getObject(id);
          classifier = cdoObject.eClass();
          object = cdoObject.cdoInternalInstance();
        }
      }
      else if (contextParameter instanceof EClassifier)
      {
        classifier = (EClassifier)contextParameter;
        object = null;
      }
      else
      {
        CDOPackageRegistry packageRegistry = view.getSession().getPackageRegistry();
        classifier = getArbitraryContextClassifier(packageRegistry);
        object = null;
      }
    }

    public ContextParameter(EClassifier classifier, EObject object)
    {
      this.classifier = classifier;
      this.object = object;
    }

    public EClassifier getClassifier()
    {
      return classifier;
    }

    public EObject getObject()
    {
      return object;
    }

    protected static EClassifier getArbitraryContextClassifier(CDOPackageRegistry packageRegistry)
    {
      for (CDOPackageUnit packageUnit : packageRegistry.getPackageUnits())
      {
        for (CDOPackageInfo packageInfo : packageUnit.getPackageInfos())
        {
          for (EClassifier classifier : packageInfo.getEPackage().getEClassifiers())
          {
            return classifier;
          }
        }
      }

      throw new IllegalStateException("Context missing");
    }
  }
}
