/*
 * Copyright (c) 2011-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
 *    Simon McDuff - bug 201266
 *    Eike Stepper & Simon McDuff - bug 204890
 *    Simon McDuff - bug 246705
 *    Simon McDuff - bug 246622
 *    Christian W. Damus (CEA) - bug 400236: get internal instance of objects in ID conversion
 */
package org.eclipse.emf.internal.cdo.view;

import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOType;
import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
import org.eclipse.emf.cdo.common.revision.CDOList;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOAddFeatureDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOClearFeatureDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOContainerFeatureDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOMoveFeatureDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDORemoveFeatureDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOUnsetFeatureDeltaImpl;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.cdo.view.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;

import org.eclipse.emf.internal.cdo.bundle.OM;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.InternalEObject.EStore;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.spi.cdo.CDOStore;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOView;

import java.text.MessageFormat;
import java.util.List;

/**
 * CDORevision needs to follow these rules:<br>
 * - Keep CDOID only when the object (!isNew && !isTransient) // Only when CDOID will not changed.<br>
 * - Keep EObject for external reference, new, transient and that until commit time.<br>
 * It is important since these objects could changed and we need to keep a reference to {@link EObject} until the end.
 * It is the reason why {@link CDOStoreImpl} always call {@link InternalCDOView#convertObjectToID(Object, boolean)} with
 * true.
 *
 * @author Eike Stepper
 */
public final class CDOStoreImpl implements CDOStore
{
  private final ContextTracer TRACER = new ContextTracer(OM.DEBUG_STORE, CDOStoreImpl.class);

  private InternalCDOView view;

  public CDOStoreImpl(InternalCDOView view)
  {
    this.view = view;
  }

  public InternalCDOView getView()
  {
    return view;
  }

  /**
   * @category READ
   */
  public InternalEObject getContainer(InternalEObject eObject)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("getContainer({0})", cdoObject); //$NON-NLS-1$
      }

      InternalCDORevision revision = readRevision(cdoObject);
      return (InternalEObject)convertIDToObject(view, cdoObject, null, -1, revision.getContainerID());
    }
  }

  /**
   * @category READ
   */
  public int getContainingFeatureID(InternalEObject eObject)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("getContainingFeatureID({0})", cdoObject); //$NON-NLS-1$
      }

      InternalCDORevision revision = readRevision(cdoObject);
      return revision.getContainingFeatureID();
    }
  }

  /**
   * @category READ
   */
  public InternalEObject getResource(InternalEObject eObject)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("getResource({0})", cdoObject); //$NON-NLS-1$
      }

      InternalCDORevision revision = readRevision(cdoObject);
      return (InternalEObject)convertIDToObject(view, cdoObject, null, -1, revision.getResourceID());
    }
  }

  /**
   * @category READ
   */
  public EStructuralFeature getContainingFeature(InternalEObject eObject)
  {
    throw new UnsupportedOperationException("Use getContainingFeatureID() instead"); //$NON-NLS-1$
  }

  /**
   * @category READ
   */
  public Object get(InternalEObject eObject, EStructuralFeature feature, int index)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("get({0}, {1}, {2})", cdoObject, feature, index); //$NON-NLS-1$
      }

      CDOFeatureAnalyzer featureAnalyzer = view.options().getFeatureAnalyzer();

      featureAnalyzer.preTraverseFeature(cdoObject, feature, index);
      InternalCDORevision revision = readRevision(cdoObject);

      Object value = revision.get(feature, index);
      value = convertToEMF(eObject, revision, feature, index, value);

      featureAnalyzer.postTraverseFeature(cdoObject, feature, index, value);
      return value;
    }
  }

  /**
   * @category READ
   */
  public boolean isSet(InternalEObject eObject, EStructuralFeature feature)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("isSet({0}, {1})", cdoObject, feature); //$NON-NLS-1$
      }

      InternalCDORevision revision = readRevision(cdoObject);
      if (feature.isMany())
      {
        CDOList list = revision.getList(feature);
        return list != null && !list.isEmpty();
      }

      Object value = revision.getValue(feature);
      if (feature.isUnsettable())
      {
        return value != null;
      }

      if (value == null)
      {
        return false;
      }

      value = convertToEMF(eObject, revision, feature, NO_INDEX, value);
      Object defaultValue = feature.getDefaultValue();
      return !ObjectUtil.equals(value, defaultValue);
    }
  }

  /**
   * @category READ
   */
  public int size(InternalEObject eObject, EStructuralFeature feature)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("size({0}, {1})", cdoObject, feature); //$NON-NLS-1$
      }

      InternalCDORevision revision = readRevision(cdoObject);
      return revision.size(feature);
    }
  }

  /**
   * @category READ
   */
  public boolean isEmpty(InternalEObject eObject, EStructuralFeature feature)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("isEmpty({0}, {1})", cdoObject, feature); //$NON-NLS-1$
      }

      InternalCDORevision revision = readRevision(cdoObject);
      return revision.isEmpty(feature);
    }
  }

  /**
   * @category READ
   */
  public boolean contains(InternalEObject eObject, EStructuralFeature feature, Object value)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("contains({0}, {1}, {2})", cdoObject, feature, value); //$NON-NLS-1$
      }

      Object convertedValue = convertToCDO(cdoObject, feature, value);

      InternalCDORevision revision = readRevision(cdoObject);
      boolean result = revision.contains(feature, convertedValue);

      // Special handling of detached (TRANSIENT) objects, see bug 354395
      if (!result && value != convertedValue && value instanceof EObject)
      {
        result = revision.contains(feature, value);
      }

      return result;
    }
  }

  /**
   * @category READ
   */
  public int indexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("indexOf({0}, {1}, {2})", cdoObject, feature, value); //$NON-NLS-1$
      }

      value = convertToCDO(cdoObject, feature, value);

      InternalCDORevision revision = readRevision(cdoObject);
      return revision.indexOf(feature, value);
    }
  }

  /**
   * @category READ
   */
  public int lastIndexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("lastIndexOf({0}, {1}, {2})", cdoObject, feature, value); //$NON-NLS-1$
      }

      value = convertToCDO(cdoObject, feature, value);

      InternalCDORevision revision = readRevision(cdoObject);
      return revision.lastIndexOf(feature, value);
    }
  }

  /**
   * @category READ
   */
  public int hashCode(InternalEObject eObject, EStructuralFeature feature)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("hashCode({0}, {1})", cdoObject, feature); //$NON-NLS-1$
      }

      InternalCDORevision revision = readRevision(cdoObject);
      return revision.hashCode(feature);
    }
  }

  /**
   * @category READ
   */
  public Object[] toArray(InternalEObject eObject, EStructuralFeature feature)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("toArray({0}, {1})", cdoObject, feature); //$NON-NLS-1$
      }

      InternalCDORevision revision = readRevision(cdoObject);
      Object[] result = revision.toArray(feature);
      for (int i = 0; i < result.length; i++)
      {
        result[i] = convertToEMF(eObject, revision, feature, i, result[i]);
      }

      // // TODO Clarify feature maps
      // if (feature instanceof EReference)
      // {
      // for (int i = 0; i < result.length; i++)
      // {
      // result[i] = resolveProxy(revision, feature, i, result[i]);
      // result[i] = convertIdToObject(cdoObject.cdoView(), eObject, feature, i, result[i]);
      // }
      // }

      return result;
    }
  }

  /**
   * @category READ
   */
  @SuppressWarnings("unchecked")
  public <T> T[] toArray(InternalEObject eObject, EStructuralFeature feature, T[] a)
  {
    synchronized (view)
    {
      Object[] array = toArray(eObject, feature);
      int size = array.length;

      if (a.length < size)
      {
        a = (T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
      }

      System.arraycopy(array, 0, a, 0, size);
      if (a.length > size)
      {
        a[size] = null;
      }

      return a;
    }
  }

  /**
   * @category WRITE
   */
  public void setContainer(InternalEObject eObject, CDOResource newResource, InternalEObject newEContainer,
      int newContainerFeatureID)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("setContainer({0}, {1}, {2}, {3})", cdoObject, newResource, newEContainer, newContainerFeatureID); //$NON-NLS-1$
      }

      Object newContainerID = newEContainer == null ? CDOID.NULL : view.convertObjectToID(newEContainer, true);
      CDOID newResourceID = newResource == null ? CDOID.NULL : newResource.cdoID();

      CDOFeatureDelta delta = new CDOContainerFeatureDeltaImpl(newResourceID, newContainerID, newContainerFeatureID);
      writeRevision(cdoObject, delta);
    }
  }

  /**
   * @category WRITE RESULT
   */
  public Object set(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("set({0}, {1}, {2}, {3})", cdoObject, feature, index, value); //$NON-NLS-1$
      }

      value = convertToCDO(cdoObject, feature, value);

      // TODO: Use writeRevision() result!!
      InternalCDORevision oldRevision = readRevision(cdoObject);
      Object oldValue = oldRevision.get(feature, index);
      oldValue = convertToEMF(eObject, oldRevision, feature, index, oldValue);

      CDOFeatureDelta delta = new CDOSetFeatureDeltaImpl(feature, index, value, oldValue);
      writeRevision(cdoObject, delta);

      return oldValue;
    }
  }

  /**
   * @category WRITE
   */
  public void unset(InternalEObject eObject, EStructuralFeature feature)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("unset({0}, {1})", cdoObject, feature); //$NON-NLS-1$
      }

      if (feature.isMany())
      {
        Object object = cdoObject.eGet(feature);
        if (object instanceof List<?> && !CDOUtil.isLegacyObject(cdoObject))
        {
          List<?> list = (List<?>)object;
          list.clear();
        }
      }
      else
      {
        CDOFeatureDelta delta = new CDOUnsetFeatureDeltaImpl(feature);
        writeRevision(cdoObject, delta);
      }
    }
  }

  /**
   * @category WRITE
   */
  public void add(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("add({0}, {1}, {2}, {3})", cdoObject, feature, index, value); //$NON-NLS-1$
      }

      value = convertToCDO(cdoObject, feature, value);

      CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
      writeRevision(cdoObject, delta);
    }
  }

  /**
   * @category WRITE RESULT
   */
  public Object remove(InternalEObject eObject, EStructuralFeature feature, int index)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("remove({0}, {1}, {2})", cdoObject, feature, index); //$NON-NLS-1$
      }

      Object oldValue = getOldListValue(eObject, cdoObject, feature, index);

      removeElement(cdoObject, feature, index);
      return oldValue;
    }
  }

  /**
   * @category WRITE RESULT
   */
  public Object move(InternalEObject eObject, EStructuralFeature feature, int target, int source)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("move({0}, {1}, {2}, {3})", cdoObject, feature, target, source); //$NON-NLS-1$
      }

      Object oldValue = getOldListValue(eObject, cdoObject, feature, source);

      CDOFeatureDelta delta = new CDOMoveFeatureDeltaImpl(feature, target, source);
      writeRevision(cdoObject, delta);

      return oldValue;
    }
  }

  /**
   * @category WRITE
   */
  public void clear(InternalEObject eObject, EStructuralFeature feature)
  {
    synchronized (view)
    {
      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (TRACER.isEnabled())
      {
        TRACER.format("clear({0}, {1})", cdoObject, feature); //$NON-NLS-1$
      }

      CDOFeatureDelta delta = new CDOClearFeatureDeltaImpl(feature);
      writeRevision(cdoObject, delta);
    }
  }

  public EObject create(EClass eClass)
  {
    throw new UnsupportedOperationException("Use the generated factory to create objects"); //$NON-NLS-1$
  }

  @Override
  public String toString()
  {
    return MessageFormat.format("CDOStore[{0}]", view); //$NON-NLS-1$
  }

  /**
   * @since 2.0
   */
  public Object resolveProxy(InternalCDORevision revision, EStructuralFeature feature, int index, Object value)
  {
    synchronized (view)
    {
      if (value instanceof CDOElementProxy)
      {
        // Resolve proxy
        CDOElementProxy proxy = (CDOElementProxy)value;
        value = view.getSession().resolveElementProxy(revision, feature, index, proxy.getIndex());
      }

      return value;
    }
  }

  /**
   * @since 3.0
   */
  public Object convertToCDO(InternalCDOObject object, EStructuralFeature feature, Object value)
  {
    synchronized (view)
    {
      if (value != null)
      {
        if (feature instanceof EReference)
        {
          value = view.convertObjectToID(value, true);
        }
        else if (FeatureMapUtil.isFeatureMap(feature))
        {
          FeatureMap.Entry entry = (FeatureMap.Entry)value;
          EStructuralFeature innerFeature = entry.getEStructuralFeature();
          Object innerValue = entry.getValue();
          Object convertedValue = view.convertObjectToID(innerValue);
          if (convertedValue != innerValue)
          {
            value = CDORevisionUtil.createFeatureMapEntry(innerFeature, convertedValue);
          }
        }
        else
        {
          CDOType type = CDOModelUtil.getType(feature.getEType());
          if (type != null)
          {
            value = type.convertToCDO(feature.getEType(), value);
          }
        }
      }

      return value;
    }
  }

  /**
   * @since 2.0
   */
  public Object convertToEMF(EObject eObject, InternalCDORevision revision, EStructuralFeature feature, int index,
      Object value)
  {
    synchronized (view)
    {
      if (value != null)
      {
        if (feature.isMany())
        {
          if (index == EStore.NO_INDEX)
          {
            return value;
          }

          value = resolveProxy(revision, feature, index, value);
          if (value instanceof CDOID)
          {
            CDOID id = (CDOID)value;
            CDOList list = revision.getList(feature);
            CDORevisionPrefetchingPolicy policy = view.options().getRevisionPrefetchingPolicy();
            InternalCDORevisionManager revisionManager = view.getSession().getRevisionManager();
            List<CDOID> listOfIDs = policy.loadAhead(revisionManager, view, eObject, feature, list, index, id);
            if (!listOfIDs.isEmpty())
            {
              int initialChunkSize = view.getSession().options().getCollectionLoadingPolicy().getInitialChunkSize();
              revisionManager.getRevisions(listOfIDs, view, initialChunkSize, CDORevision.DEPTH_NONE, true);
            }
          }
        }

        if (feature instanceof EReference)
        {
          value = convertIDToObject(view, eObject, feature, index, value);
        }
        else if (FeatureMapUtil.isFeatureMap(feature))
        {
          FeatureMap.Entry entry = (FeatureMap.Entry)value;
          EStructuralFeature innerFeature = entry.getEStructuralFeature();
          Object innerValue = entry.getValue();
          Object convertedValue = convertIDToObject(view, eObject, feature, index, innerValue);
          if (convertedValue != innerValue)
          {
            value = FeatureMapUtil.createEntry(innerFeature, convertedValue);
          }
        }
        else
        {
          CDOType type = CDOModelUtil.getType(feature.getEType());
          if (type != null)
          {
            value = type.convertToEMF(feature.getEType(), value);
          }
        }
      }

      return value;
    }
  }

  private Object convertIDToObject(InternalCDOView view, EObject eObject, EStructuralFeature feature, int index,
      Object value)
  {
    try
    {
      value = view.convertIDToObject(value);
    }
    catch (ObjectNotFoundException ex)
    {
      if (value instanceof CDOID)
      {
        // If feature == null then we come from getContainer()/getResource() and are in case of detached object
        // consequently to a remote parent object remove then must return null
        if (feature != null)
        {
          CDOStaleReferencePolicy staleReferencePolicy = view.options().getStaleReferencePolicy();
          value = staleReferencePolicy.processStaleReference(eObject, feature, index, ex.getID());
        }
        else
        {
          value = null;
        }
      }
    }

    return getInternalInstance(value);
  }

  private InternalCDOObject getCDOObject(Object object)
  {
    return FSMUtil.adapt(object, view);
  }

  private Object getInternalInstance(Object object)
  {
    if (object instanceof InternalCDOObject)
    {
      return ((InternalCDOObject)object).cdoInternalInstance();
    }

    return object;
  }

  private Object getOldListValue(InternalEObject eObject, InternalCDOObject cdoObject, EStructuralFeature feature,
      int index)
  {
    if (!feature.isMany())
    {
      throw new UnsupportedOperationException("Not supported for single-valued features");
    }

    // Bug 293283 / Bug 314387
    InternalCDORevision revision = readRevision(cdoObject);
    CDOList list = revision.getList(feature);
    int size = list.size();
    if (index < 0 || size <= index)
    {
      throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
    }

    Object oldValue = revision.get(feature, index);
    oldValue = convertToEMF(eObject, revision, feature, index, oldValue);
    return oldValue;
  }

  private static InternalCDORevision readRevision(InternalCDOObject cdoObject)
  {
    InternalCDORevision revision = CDOStateMachine.INSTANCE.read(cdoObject);
    if (revision == null)
    {
      throw new IllegalStateException("revision == null");
    }

    return revision;
  }

  private static Object writeRevision(InternalCDOObject cdoObject, CDOFeatureDelta delta)
  {
    return CDOStateMachine.INSTANCE.write(cdoObject, delta);
  }

  public static void removeElement(InternalCDOObject cdoObject, EStructuralFeature feature, int index)
  {
    CDOFeatureDelta delta = new CDORemoveFeatureDeltaImpl(feature, index);
    writeRevision(cdoObject, delta);
  }
}
