/***************************************************************************
 * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
 * 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 - http://bugs.eclipse.org/201266
 *    Eike Stepper & Simon McDuff - http://bugs.eclipse.org/204890
 *    Simon McDuff - http://bugs.eclipse.org/246705
 *    Simon McDuff - http://bugs.eclipse.org/246622
 **************************************************************************/
package org.eclipse.emf.internal.cdo;

import org.eclipse.emf.cdo.CDORevisionPrefetchingPolicy;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOFeature;
import org.eclipse.emf.cdo.common.model.CDOType;
import org.eclipse.emf.cdo.common.revision.CDOList;
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.model.core.CDOFeatureMapEntryDataTypeImpl;
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.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.revision.CDOElementProxy;
import org.eclipse.emf.internal.cdo.util.FSMUtil;

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

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.InternalEObject.EStore;
import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMapUtil;

import java.text.MessageFormat;
import java.util.Collection;

/**
 * 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 CDOStore} always call {@link InternalCDOView#convertObjectToID(Object, boolean)} with
 * true.
 * 
 * @author Eike Stepper
 */
public final class CDOStore implements EStore
{
  private final ContextTracer TRACER = new ContextTracer(OM.DEBUG_STORE, CDOStore.class);

  private InternalCDOView view;

  // Used for optimization. Multiple call to CDStore will be sent like size and than add.
  private EStructuralFeature lastLookupEFeature;

  private CDOFeature lastLookupCDOFeature;

  private Object lock = new Object();

  /**
   * @since 2.0
   */
  public CDOStore(InternalCDOView view)
  {
    this.view = view;
  }

  /**
   * @since 2.0
   */
  public InternalCDOView getView()
  {
    return view;
  }

  /**
   * @since 2.0
   */
  public void setContainer(InternalEObject eObject, CDOResource newResource, InternalEObject newEContainer,
      int newContainerFeatureID)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    if (TRACER.isEnabled())
    {
      TRACER.format("setContainer({0}, {1}, {2}, {3})", cdoObject, newResource, newEContainer, newContainerFeatureID);
    }

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

    CDOFeatureDelta delta = new CDOContainerFeatureDeltaImpl(newResourceID, newContainerID, newContainerFeatureID);
    InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
    revision.setResourceID(newResourceID);
    revision.setContainerID(newContainerID);
    revision.setContainingFeatureID(newContainerFeatureID);
  }

  public InternalEObject getContainer(InternalEObject eObject)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    if (TRACER.isEnabled())
    {
      TRACER.format("getContainer({0})", cdoObject);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    return (InternalEObject)cdoObject.cdoView().convertIDToObject(revision.getContainerID());
  }

  public int getContainingFeatureID(InternalEObject eObject)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    if (TRACER.isEnabled())
    {
      TRACER.format("getContainingFeatureID({0})", cdoObject);
    }

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

  /**
   * @since 2.0
   */
  public InternalEObject getResource(InternalEObject eObject)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    if (TRACER.isEnabled())
    {
      TRACER.format("getResource({0})", cdoObject);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    return (InternalEObject)cdoObject.cdoView().convertIDToObject(revision.getResourceID());
  }

  @Deprecated
  public EStructuralFeature getContainingFeature(InternalEObject eObject)
  {
    throw new UnsupportedOperationException("Use getContainingFeatureID() instead");
  }

  public Object get(InternalEObject eObject, EStructuralFeature eFeature, int index)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("get({0}, {1}, {2})", cdoObject, cdoFeature, index);
    }

    view.getFeatureAnalyzer().preTraverseFeature(cdoObject, cdoFeature, index);
    InternalCDORevision revision = getRevisionForReading(cdoObject);

    Object value = revision.basicGet(cdoFeature, index);
    value = convertToEMF(view, eObject, revision, eFeature, cdoFeature, index, value);

    view.getFeatureAnalyzer().postTraverseFeature(cdoObject, cdoFeature, index, value);
    return value;
  }

  @Deprecated
  public boolean isSet(InternalEObject eObject, EStructuralFeature eFeature)
  {
    // Should not be called
    throw new ImplementationError();
  }

  public int size(InternalEObject eObject, EStructuralFeature eFeature)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("size({0}, {1})", cdoObject, cdoFeature);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    return revision.size(cdoFeature);
  }

  public boolean isEmpty(InternalEObject eObject, EStructuralFeature eFeature)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("isEmpty({0}, {1})", cdoObject, cdoFeature);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    return revision.isEmpty(cdoFeature);
  }

  public boolean contains(InternalEObject eObject, EStructuralFeature eFeature, Object value)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("contains({0}, {1}, {2})", cdoObject, cdoFeature, value);
    }

    if (cdoFeature.isReference())
    {
      value = cdoObject.cdoView().convertObjectToID(value, true);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    return revision.contains(cdoFeature, value);
  }

  public int indexOf(InternalEObject eObject, EStructuralFeature eFeature, Object value)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("indexOf({0}, {1}, {2})", cdoObject, cdoFeature, value);
    }

    if (cdoFeature.isReference())
    {
      value = cdoObject.cdoView().convertObjectToID(value, true);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    return revision.indexOf(cdoFeature, value);
  }

  public int lastIndexOf(InternalEObject eObject, EStructuralFeature eFeature, Object value)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("lastIndexOf({0}, {1}, {2})", cdoObject, cdoFeature, value);
    }

    if (cdoFeature.isReference())
    {
      value = cdoObject.cdoView().convertObjectToID(value, true);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    return revision.lastIndexOf(cdoFeature, value);
  }

  public int hashCode(InternalEObject eObject, EStructuralFeature eFeature)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("hashCode({0}, {1})", cdoObject, cdoFeature);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    return revision.hashCode(cdoFeature);
  }

  public Object[] toArray(InternalEObject eObject, EStructuralFeature eFeature)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("toArray({0}, {1})", cdoObject, cdoFeature);
    }

    InternalCDORevision revision = getRevisionForReading(cdoObject);
    Object[] result = revision.toArray(cdoFeature);
    if (cdoFeature.isReference())
    {
      for (int i = 0; i < result.length; i++)
      {
        result[i] = resolveProxy(revision, cdoFeature, i, result[i]);
        result[i] = cdoObject.cdoView().convertIDToObject(result[i]);
      }
    }

    return result;
  }

  @SuppressWarnings("unchecked")
  public <T> T[] toArray(InternalEObject eObject, EStructuralFeature eFeature, T[] a)
  {
    Object[] array = toArray(eObject, eFeature);
    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;
  }

  public Object set(InternalEObject eObject, EStructuralFeature eFeature, int index, Object value)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("set({0}, {1}, {2}, {3})", cdoObject, cdoFeature, index, value);
    }

    value = convertToCDO(getView(), eFeature, cdoFeature, value);

    CDOFeatureDelta delta = new CDOSetFeatureDeltaImpl(cdoFeature, index, value);
    InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
    if (cdoFeature.isReference())
    {
      Object oldValue = revision.basicGet(cdoFeature, index);
      oldValue = resolveProxy(revision, cdoFeature, index, oldValue);
      value = cdoObject.cdoView().convertObjectToID(value, true);
    }

    Object oldValue = revision.basicSet(cdoFeature, index, value);
    oldValue = convertToEMF(cdoObject.cdoView(), eObject, revision, eFeature, cdoFeature, index, oldValue);
    return oldValue;
  }

  /**
   * @since 2.0
   */
  public Object convertToEMF(InternalCDOView view, EObject eObject, InternalCDORevision revision,
      EStructuralFeature eFeature, CDOFeature cdoFeature, int index, Object value)
  {
    if (value != null)
    {
      if (value == InternalCDORevision.NIL)
      {
        return EStoreEObjectImpl.NIL;
      }

      if (cdoFeature.isMany() && EStore.NO_INDEX != index)
      {
        value = resolveProxy(revision, cdoFeature, index, value);
        if (cdoFeature.isMany() && value instanceof CDOID)
        {
          CDOID id = (CDOID)value;
          CDOList list = revision.getList(cdoFeature);
          CDORevisionManagerImpl revisionManager = (CDORevisionManagerImpl)view.getSession().getRevisionManager();
          CDORevisionPrefetchingPolicy policy = view.options().getRevisionPrefetchingPolicy();
          Collection<CDOID> listOfIDs = policy.loadAhead(revisionManager, eObject, eFeature, list, index, id);
          if (!listOfIDs.isEmpty())
          {
            revisionManager.getRevisions(listOfIDs, view.getSession().options().getCollectionLoadingPolicy()
                .getInitialChunkSize());
          }
        }
      }

      if (cdoFeature.isReference())
      {
        value = view.convertIDToObject(value);
      }
      else if (cdoFeature.getType() == CDOType.CUSTOM)
      {
        value = EcoreUtil.createFromString((EDataType)eFeature.getEType(), (String)value);
      }
      else if (cdoFeature.getType() == CDOType.FEATURE_MAP_ENTRY)
      {
        CDOFeatureMapEntryDataTypeImpl entry = (CDOFeatureMapEntryDataTypeImpl)value;
        EStructuralFeature feature = (EStructuralFeature)view.getResourceSet().getEObject(
            URI.createURI(entry.getURI()), true);
        Object object = view.convertIDToObject(entry.getObject());
        value = FeatureMapUtil.createEntry(feature, object);
      }
    }

    return value;
  }

  /**
   * @since 2.0
   */
  public Object convertToCDO(InternalCDOView view, EStructuralFeature eFeature, CDOFeature cdoFeature, Object value)
  {
    if (value != null)
    {
      if (value == EStoreEObjectImpl.NIL)
      {
        value = InternalCDORevision.NIL;
      }
      else if (cdoFeature.isReference())
      {
        value = view.convertObjectToID(value, true);
      }
      else if (cdoFeature.getType() == CDOType.FEATURE_MAP_ENTRY)
      {
        FeatureMap.Entry entry = (FeatureMap.Entry)value;
        String uri = EcoreUtil.getURI(entry.getEStructuralFeature()).toString();
        value = CDORevisionUtil.createFeatureMapEntry(uri, entry.getValue());
      }
      else if (cdoFeature.getType() == CDOType.CUSTOM)
      {
        value = EcoreUtil.convertToString((EDataType)eFeature.getEType(), value);
      }
    }

    return value;
  }

  public void unset(InternalEObject eObject, EStructuralFeature eFeature)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("unset({0}, {1})", cdoObject, cdoFeature);
    }

    CDOFeatureDelta delta = new CDOUnsetFeatureDeltaImpl(cdoFeature);
    InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);

    // TODO Handle containment remove!!!
    revision.set(cdoFeature, 0, null);
  }

  public void add(InternalEObject eObject, EStructuralFeature eFeature, int index, Object value)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("add({0}, {1}, {2}, {3})", cdoObject, cdoFeature, index, value);
    }

    value = convertToCDO(cdoObject.cdoView(), eFeature, cdoFeature, value);

    CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(cdoFeature, index, value);
    InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
    revision.add(cdoFeature, index, value);
  }

  public Object remove(InternalEObject eObject, EStructuralFeature eFeature, int index)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("remove({0}, {1}, {2})", cdoObject, cdoFeature, index);
    }

    CDOFeatureDelta delta = new CDORemoveFeatureDeltaImpl(cdoFeature, index);
    InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
    Object result = revision.remove(cdoFeature, index);

    result = convertToEMF(cdoObject.cdoView(), eObject, revision, eFeature, cdoFeature, index, result);

    return result;
  }

  public void clear(InternalEObject eObject, EStructuralFeature eFeature)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("clear({0}, {1})", cdoObject, cdoFeature);
    }

    CDOFeatureDelta delta = new CDOClearFeatureDeltaImpl(cdoFeature);
    InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
    // TODO Handle containment remove!!!
    revision.clear(cdoFeature);
  }

  public Object move(InternalEObject eObject, EStructuralFeature eFeature, int target, int source)
  {
    InternalCDOObject cdoObject = getCDOObject(eObject);
    CDOFeature cdoFeature = getCDOFeature(cdoObject, eFeature);
    if (TRACER.isEnabled())
    {
      TRACER.format("move({0}, {1}, {2}, {3})", cdoObject, cdoFeature, target, source);
    }

    CDOFeatureDelta delta = new CDOMoveFeatureDeltaImpl(cdoFeature, target, source);
    InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
    Object result = revision.move(cdoFeature, target, source);

    result = convertToEMF(cdoObject.cdoView(), eObject, revision, eFeature, cdoFeature, EStore.NO_INDEX, result);
    return result;
  }

  public EObject create(EClass eClass)
  {
    throw new UnsupportedOperationException("Use the generated factory to create objects");
  }

  @Override
  public String toString()
  {
    return MessageFormat.format("CDOStore[{0}]", view);
  }

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

  /**
   * @since 2.0
   */
  public Object resolveProxy(InternalCDORevision revision, CDOFeature cdoFeature, int index, Object value)
  {
    if (value instanceof CDOElementProxy)
    {
      value = ((CDOElementProxy)value)
          .resolve(getView().getSession().getRevisionManager(), revision, cdoFeature, index);
    }

    return value;
  }

  private CDOFeature getCDOFeature(InternalCDOObject cdoObject, EStructuralFeature eFeature)
  {
    synchronized (lock)
    {
      if (eFeature == lastLookupEFeature)
      {
        return lastLookupCDOFeature;
      }
    }

    InternalCDOView view = cdoObject.cdoView();
    if (view == null)
    {
      throw new IllegalStateException("view == null");
    }

    CDOSessionPackageManagerImpl packageManager = (CDOSessionPackageManagerImpl)view.getSession().getPackageManager();
    CDOFeature cdoFeature = packageManager.getCDOFeature(eFeature);

    synchronized (lock)
    {
      lastLookupEFeature = eFeature;
      lastLookupCDOFeature = cdoFeature;
    }

    return cdoFeature;
  }

  private static InternalCDORevision getRevisionForReading(InternalCDOObject cdoObject)
  {
    CDOStateMachine.INSTANCE.read(cdoObject);
    return getRevision(cdoObject);
  }

  private static InternalCDORevision getRevisionForWriting(InternalCDOObject cdoObject, CDOFeatureDelta delta)
  {
    CDOStateMachine.INSTANCE.write(cdoObject, delta);
    return getRevision(cdoObject);
  }

  private static InternalCDORevision getRevision(InternalCDOObject cdoObject)
  {
    InternalCDORevision revision = cdoObject.cdoRevision();
    if (revision == null)
    {
      throw new IllegalStateException("revision == null");
    }

    return revision;
  }
}
