/*
 * Copyright (c) 2009-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
 *    Simon McDuff - bug 230832
 */
package org.eclipse.emf.cdo.internal.common.revision;

import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.branch.CDOBranchPointRange;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionCache;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.CDORevisionsLoadedEvent;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
import org.eclipse.emf.cdo.spi.common.revision.SyntheticCDORevision;

import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.event.Event;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.ecore.EClass;

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

/**
 * @author Eike Stepper
 */
public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevisionManager
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CDORevisionManagerImpl.class);

  private boolean supportingAudits;

  private boolean supportingBranches;

  private RevisionLoader revisionLoader;

  private RevisionLocker revisionLocker;

  private CDORevisionFactory factory;

  private InternalCDORevisionCache cache;

  @ExcludeFromDump
  private transient Object loadAndAddLock = new Object()
  {
    @Override
    public String toString()
    {
      return "LoadAndAddLock"; //$NON-NLS-1$
    }
  };

  @ExcludeFromDump
  private transient Object reviseLock = new Object()
  {
    @Override
    public String toString()
    {
      return "ReviseLock"; //$NON-NLS-1$
    }
  };

  public CDORevisionManagerImpl()
  {
  }

  public boolean isSupportingAudits()
  {
    return supportingAudits;
  }

  public void setSupportingAudits(boolean on)
  {
    checkInactive();
    supportingAudits = on;
  }

  public boolean isSupportingBranches()
  {
    return supportingBranches;
  }

  public void setSupportingBranches(boolean on)
  {
    checkInactive();
    supportingBranches = on;
  }

  public RevisionLoader getRevisionLoader()
  {
    return revisionLoader;
  }

  public void setRevisionLoader(RevisionLoader revisionLoader)
  {
    checkInactive();
    this.revisionLoader = revisionLoader;
  }

  public RevisionLocker getRevisionLocker()
  {
    return revisionLocker;
  }

  public void setRevisionLocker(RevisionLocker revisionLocker)
  {
    checkInactive();
    this.revisionLocker = revisionLocker;
  }

  public CDORevisionFactory getFactory()
  {
    return factory;
  }

  public void setFactory(CDORevisionFactory factory)
  {
    checkInactive();
    this.factory = factory;
  }

  public InternalCDORevisionCache getCache()
  {
    return cache;
  }

  public void setCache(CDORevisionCache cache)
  {
    checkInactive();
    this.cache = (InternalCDORevisionCache)cache;
  }

  public EClass getObjectType(CDOID id, CDOBranchManager branchManagerForLoadOnDemand)
  {
    EClass type = cache.getObjectType(id);
    if (type == null && branchManagerForLoadOnDemand != null)
    {
      CDOBranch mainBranch = branchManagerForLoadOnDemand.getMainBranch();
      CDORevision revision = getRevisionByVersion(id, mainBranch.getVersion(CDOBranchVersion.FIRST_VERSION), 0, true);
      if (revision != null)
      {
        type = revision.getEClass();
      }
    }

    return type;
  }

  public EClass getObjectType(CDOID id)
  {
    return getObjectType(id, null);
  }

  public boolean containsRevision(CDOID id, CDOBranchPoint branchPoint)
  {
    if (supportingBranches)
    {
      return getRevision(id, branchPoint, CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE, false, null) != null;
    }

    return getCachedRevision(id, branchPoint) != null;
  }

  public boolean containsRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
  {
    return cache.getRevisionByVersion(id, branchVersion) != null;
  }

  public void reviseLatest(CDOID id, CDOBranch branch)
  {
    acquireAtomicRequestLock(reviseLock);

    try
    {
      InternalCDORevision revision = (InternalCDORevision)cache.getRevision(id, branch.getHead());
      if (revision != null)
      {
        CDOBranchVersion version = branch.getVersion(revision.getVersion());
        cache.removeRevision(id, version);
      }
    }
    finally
    {
      releaseAtomicRequestLock(reviseLock);
    }
  }

  public void reviseVersion(CDOID id, CDOBranchVersion branchVersion, long timeStamp)
  {
    acquireAtomicRequestLock(reviseLock);

    try
    {
      InternalCDORevision revision = getCachedRevisionByVersion(id, branchVersion);
      if (revision != null)
      {
        if (timeStamp == CDORevision.UNSPECIFIED_DATE || !supportingAudits)
        {
          cache.removeRevision(id, branchVersion);
        }

        revision.setRevised(timeStamp - 1);
      }
    }
    finally
    {
      releaseAtomicRequestLock(reviseLock);
    }
  }

  public InternalCDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk,
      boolean loadOnDemand)
  {
    checkArg(branchVersion.getVersion() >= CDOBranchVersion.FIRST_VERSION,
        "Invalid version: " + branchVersion.getVersion());
    acquireAtomicRequestLock(loadAndAddLock);

    try
    {
      InternalCDORevision revision = getCachedRevisionByVersion(id, branchVersion);
      if (revision == null)
      {
        if (loadOnDemand)
        {
          if (TRACER.isEnabled())
          {
            TRACER.format("Loading revision {0} from {1}", id, branchVersion); //$NON-NLS-1$
          }

          revision = revisionLoader.loadRevisionByVersion(id, branchVersion, referenceChunk);
          addRevision(revision);
        }
      }

      return revision;
    }
    finally
    {
      releaseAtomicRequestLock(loadAndAddLock);
    }
  }

  public CDOBranchPointRange getObjectLifetime(CDOID id, CDOBranchPoint branchPoint)
  {
    if (revisionLoader instanceof RevisionLoader2)
    {
      RevisionLoader2 revisionLoader2 = (RevisionLoader2)revisionLoader;
      return revisionLoader2.loadObjectLifetime(id, branchPoint);
    }

    return null;
  }

  public InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth,
      boolean loadOnDemand)
  {
    return getRevision(id, branchPoint, referenceChunk, prefetchDepth, loadOnDemand, null);
  }

  public InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth,
      boolean loadOnDemand, SyntheticCDORevision[] synthetics)
  {
    List<CDOID> ids = Collections.singletonList(id);
    CDORevision result = getRevisions(ids, branchPoint, referenceChunk, prefetchDepth, loadOnDemand, synthetics).get(0);
    return (InternalCDORevision)result;
  }

  public List<CDORevision> getRevisions(List<CDOID> ids, CDOBranchPoint branchPoint, int referenceChunk,
      int prefetchDepth, boolean loadOnDemand)
  {
    return getRevisions(ids, branchPoint, referenceChunk, prefetchDepth, loadOnDemand, null);
  }

  public List<CDORevision> getRevisions(List<CDOID> ids, CDOBranchPoint branchPoint, int referenceChunk,
      int prefetchDepth, boolean loadOnDemand, SyntheticCDORevision[] synthetics)
  {
    RevisionInfo[] infos = new RevisionInfo[ids.size()];
    List<RevisionInfo> infosToLoad = createRevisionInfos(ids, branchPoint, prefetchDepth, loadOnDemand, infos);
    if (infosToLoad != null)
    {
      List<? extends CDORevision> additionalLoadedRevisions //
      = loadRevisions(infosToLoad, branchPoint, referenceChunk, prefetchDepth);

      List<? extends CDORevision> primaryLoadedRevisions //
      = getResultsAndSynthetics(infosToLoad.toArray(new RevisionInfo[0]), null);

      if (primaryLoadedRevisions != null && !primaryLoadedRevisions.isEmpty()
          || additionalLoadedRevisions != null && !additionalLoadedRevisions.isEmpty())
      {
        if (primaryLoadedRevisions == null)
        {
          primaryLoadedRevisions = Collections.emptyList();
        }

        if (additionalLoadedRevisions == null)
        {
          additionalLoadedRevisions = Collections.emptyList();
        }

        fireEvent(new RevisionsLoadedEvent(this, primaryLoadedRevisions, additionalLoadedRevisions, prefetchDepth));
      }
    }

    return getResultsAndSynthetics(infos, synthetics);
  }

  public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
      CDORevisionHandler handler)
  {
    revisionLoader.handleRevisions(eClass, branch, exactBranch, timeStamp, exactTime, handler);
  }

  @Override
  public String toString()
  {
    return "RevisionManager";
  }

  private List<RevisionInfo> createRevisionInfos(List<CDOID> ids, CDOBranchPoint branchPoint, int prefetchDepth,
      boolean loadOnDemand, RevisionInfo[] infos)
  {
    List<RevisionInfo> infosToLoad = null;
    Iterator<CDOID> idIterator = ids.iterator();
    for (int i = 0; i < infos.length; i++)
    {
      CDOID id = idIterator.next();
      RevisionInfo info = createRevisionInfo(id, branchPoint);
      infos[i] = info;

      if (loadOnDemand && (prefetchDepth != CDORevision.DEPTH_NONE || info.isLoadNeeded()))
      {
        if (infosToLoad == null)
        {
          infosToLoad = new ArrayList<RevisionInfo>(1);
        }

        infosToLoad.add(info);
      }
    }

    return infosToLoad;
  }

  private RevisionInfo createRevisionInfo(CDOID id, CDOBranchPoint branchPoint)
  {
    InternalCDORevision revision = getCachedRevision(id, branchPoint);
    if (revision != null)
    {
      return createRevisionInfoAvailable(revision, branchPoint);
    }

    if (supportingBranches)
    {
      revision = getCachedRevisionRecursively(id, branchPoint);
      if (revision != null)
      {
        return createRevisionInfoAvailable(revision, branchPoint);
      }
    }

    return createRevisionInfoMissing(id, branchPoint);
  }

  private RevisionInfo.Available createRevisionInfoAvailable(InternalCDORevision revision,
      CDOBranchPoint requestedBranchPoint)
  {
    if (revision instanceof PointerCDORevision)
    {
      PointerCDORevision pointer = (PointerCDORevision)revision;
      CDOBranchVersion target = pointer.getTarget();
      InternalCDORevision targetRevision = target == null ? null : getCachedRevisionByVersion(pointer.getID(), target);
      if (targetRevision != null)
      {
        target = targetRevision;
      }

      return new RevisionInfo.Available.Pointer(pointer.getID(), requestedBranchPoint, pointer, target);
    }

    if (revision instanceof DetachedCDORevision)
    {
      DetachedCDORevision detached = (DetachedCDORevision)revision;
      return new RevisionInfo.Available.Detached(detached.getID(), requestedBranchPoint, detached);
    }

    return new RevisionInfo.Available.Normal(revision.getID(), requestedBranchPoint, revision);
  }

  private RevisionInfo.Missing createRevisionInfoMissing(CDOID id, CDOBranchPoint requestedBranchPoint)
  {
    return new RevisionInfo.Missing(id, requestedBranchPoint);
  }

  protected List<InternalCDORevision> loadRevisions(List<RevisionInfo> infosToLoad, CDOBranchPoint branchPoint,
      int referenceChunk, int prefetchDepth)
  {
    acquireAtomicRequestLock(loadAndAddLock);

    try
    {
      List<InternalCDORevision> additionalRevisions = null;

      List<RevisionInfo> additionalRevisionInfos = //
      revisionLoader.loadRevisions(infosToLoad, branchPoint, referenceChunk, prefetchDepth);

      if (additionalRevisionInfos != null)
      {
        additionalRevisions = new ArrayList<InternalCDORevision>(additionalRevisionInfos.size());
        for (RevisionInfo info : additionalRevisionInfos)
        {
          info.processResult(this, new ArrayList<CDORevision>(), null, 0);
          additionalRevisions.add(info.getResult());
        }
      }

      return additionalRevisions;
    }
    finally
    {
      releaseAtomicRequestLock(loadAndAddLock);
    }
  }

  private List<CDORevision> getResultsAndSynthetics(RevisionInfo[] infos, SyntheticCDORevision[] synthetics)
  {
    List<CDORevision> results = new ArrayList<CDORevision>(infos.length);
    for (int i = 0; i < infos.length; i++)
    {
      RevisionInfo info = infos[i];
      info.processResult(this, results, synthetics, i);
    }

    return results;
  }

  public void addRevision(CDORevision revision)
  {
    if (revision != null)
    {
      acquireAtomicRequestLock(loadAndAddLock);

      try
      {
        if (revision instanceof PointerCDORevision)
        {
          PointerCDORevision pointer = (PointerCDORevision)revision;
          CDOBranchVersion target = pointer.getTarget();
          if (target instanceof InternalCDORevision)
          {
            revision = new PointerCDORevision(pointer.getEClass(), pointer.getID(), pointer.getBranch(),
                pointer.getRevised(), CDOBranchUtil.copyBranchVersion(target));
          }
        }

        int oldVersion = revision.getVersion() - 1;
        if (oldVersion >= CDORevision.UNSPECIFIED_VERSION)
        {
          CDOBranchVersion old = revision.getBranch().getVersion(oldVersion);
          InternalCDORevision oldRevision = getCachedRevisionByVersion(revision.getID(), old);
          if (!revision.isHistorical())
          {
            if (oldRevision != null)
            {
              oldRevision.setRevised(revision.getTimeStamp() - 1);
            }
            else
            {
              // Remove last revision from cache, which is not revised
              InternalCDORevision cachedLatestRevision = getCachedRevision(revision.getID(), revision);
              if (cachedLatestRevision != null && !cachedLatestRevision.isHistorical())
              {
                // Found revision is stale.
                // We cannot revise it now because of lack information, thus remove it from the cache
                cache.removeRevision(cachedLatestRevision.getID(), cachedLatestRevision);
              }
            }
          }
        }

        cache.addRevision(revision);
      }
      finally
      {
        releaseAtomicRequestLock(loadAndAddLock);
      }
    }
  }

  @Override
  protected void doBeforeActivate() throws Exception
  {
    super.doBeforeActivate();
    if (factory == null)
    {
      factory = CDORevisionFactory.DEFAULT;
    }

    if (cache == null)
    {
      cache = (InternalCDORevisionCache)CDORevisionUtil.createRevisionCache(supportingAudits, supportingBranches);
    }

    if (cache instanceof AbstractCDORevisionCache)
    {
      String name = revisionLoader.toString();
      ((AbstractCDORevisionCache)cache).setName(name);
    }
  }

  @Override
  protected void doActivate() throws Exception
  {
    super.doActivate();
    LifecycleUtil.activate(cache);
  }

  @Override
  protected void doDeactivate() throws Exception
  {
    LifecycleUtil.deactivate(cache);
    super.doDeactivate();
  }

  private void acquireAtomicRequestLock(Object key)
  {
    if (revisionLocker != null)
    {
      revisionLocker.acquireAtomicRequestLock(key);
    }
  }

  private void releaseAtomicRequestLock(Object key)
  {
    if (revisionLocker != null)
    {
      revisionLocker.releaseAtomicRequestLock(key);
    }
  }

  private InternalCDORevision getCachedRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
  {
    return (InternalCDORevision)cache.getRevisionByVersion(id, branchVersion);
  }

  private InternalCDORevision getCachedRevision(CDOID id, CDOBranchPoint branchPoint)
  {
    return (InternalCDORevision)cache.getRevision(id, branchPoint);
  }

  private InternalCDORevision getCachedRevisionRecursively(CDOID id, CDOBranchPoint branchPoint)
  {
    CDOBranch branch = branchPoint.getBranch();
    if (!branch.isMainBranch())
    {
      CDOBranchPoint base = branch.getBase();
      InternalCDORevision revision = getCachedRevision(id, base);
      if (revision != null)
      {
        return revision;
      }

      // Recurse
      return getCachedRevisionRecursively(id, base);
    }

    // Reached main branch
    return null;
  }

  /**
   * @author Esteban Dugueperoux
   */
  private static class RevisionsLoadedEvent extends Event implements CDORevisionsLoadedEvent
  {
    private static final long serialVersionUID = 1L;

    private List<? extends CDORevision> primaryLoadedRevisions;

    private List<? extends CDORevision> additionalLoadedRevisions;

    private int prefetchDepth;

    public RevisionsLoadedEvent(CDORevisionManager revisionManager, List<? extends CDORevision> primaryLoadedRevisions,
        List<? extends CDORevision> additionalLoadedRevisions, int prefetchDepth)
    {
      super(revisionManager);
      this.primaryLoadedRevisions = primaryLoadedRevisions;
      this.additionalLoadedRevisions = additionalLoadedRevisions;
      this.prefetchDepth = prefetchDepth;
    }

    @Override
    public CDORevisionManager getSource()
    {
      return (CDORevisionManager)super.getSource();
    }

    public List<? extends CDORevision> getPrimaryLoadedRevisions()
    {
      return primaryLoadedRevisions;
    }

    public List<? extends CDORevision> getAdditionalLoadedRevisions()
    {
      return additionalLoadedRevisions;
    }

    public int getPrefetchDepth()
    {
      return prefetchDepth;
    }
  }
}
