/*
 * Copyright (c) 2012, 2013, 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
 */
package org.eclipse.emf.cdo.compare;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.CDORevisionData;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.CDOResourceNode;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewOpener;

import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.scope.AbstractComparisonScope;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.EcoreUtil.ProperContentIterator;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOSession.MergeData;
import org.eclipse.emf.spi.cdo.InternalCDOView;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * A CDO-specific base implementation of a {@link IComparisonScope comparison scope}.
 *
 * @author Eike Stepper
 */
public abstract class CDOComparisonScope extends AbstractComparisonScope
{
  private static final CDOViewOpener DEFAULT_VIEW_OPENER = CDOCompareUtil.DEFAULT_VIEW_OPENER;

  private boolean resolveProxies = true;

  public CDOComparisonScope(Notifier left, Notifier right, Notifier origin)
  {
    super(left, right, origin);
  }

  public Iterator<? extends Resource> getCoveredResources(ResourceSet resourceSet)
  {
    return Iterators.emptyIterator();
  }

  public Iterator<? extends EObject> getCoveredEObjects(Resource resource)
  {
    return Iterators.emptyIterator();
  }

  public final boolean isResolveProxies()
  {
    return resolveProxies;
  }

  public final void setResolveProxies(boolean resolveProxies)
  {
    this.resolveProxies = resolveProxies;
  }

  private static CDOView openOriginView(CDOView leftView, CDOView rightView, CDOView[] originView,
      CDOViewOpener viewOpener)
  {
    if (leftView.getSession() != rightView.getSession())
    {
      throw new IllegalArgumentException("Sessions are different");
    }

    if (originView != null)
    {
      if (originView.length != 1)
      {
        throw new IllegalArgumentException("originView.length != 1");
      }

      if (originView[0] != null)
      {
        throw new IllegalArgumentException("originView[0] != null");
      }

      CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(leftView, rightView);
      if (!ancestor.equals(leftView) && !ancestor.equals(rightView))
      {
        if (viewOpener == DEFAULT_VIEW_OPENER)
        {
          viewOpener = leftView.getSession();
        }

        originView[0] = viewOpener.openView(ancestor, new ResourceSetImpl());
        return originView[0];
      }
    }

    return null;
  }

  /**
   * Takes an arbitrary {@link CDOObject object} (including {@link CDOResourceNode resource nodes})
   * and returns {@link Match matches} for <b>all</b> elements of its {@link EObject#eAllContents() content tree}. This scope has the advantage that the comparison can
   * be rooted at specific objects that are different from (below of) the root resource. The disadvantage is that all the transitive children of this specific object are
   * matched, whether they differ or not. Major parts of huge repositories can be loaded to the client side easily, if no attention is paid.
   * The following method returns comparisons that are based on this scope algorithm:
   * <ul>
   * <li>{@link CDOCompareUtil#compare(CDOObject, CDOView, CDOView[])}
   * </ul>
   *
   * @author Eike Stepper
   */
  public static class AllContents extends CDOComparisonScope
  {
    public AllContents(Notifier left, Notifier right, Notifier origin)
    {
      super(left, right, origin);
    }

    public Iterator<? extends EObject> getChildren(EObject eObject)
    {
      return EcoreUtil.getAllProperContents(eObject, isResolveProxies());
    }

    /**
     * Takes an arbitrary {@link CDOObject object} (including {@link CDOResourceNode resource nodes}) and returns {@link Match matches} for <b>all</b> elements of its {@link EObject#eAllContents() content tree}. This scope has the advantage that the comparison can
     * be rooted at specific objects that are different from (below of) the root resource. The disadvantage is that all the transitive children of this specific object are
     * matched, whether they differ or not. Major parts of huge repositories can be loaded to the client side easily, if no attention is paid.
     */
    public static AllContents create(CDOObject left, CDOView rightView, CDOView[] originView)
    {
      return create(left, rightView, originView, DEFAULT_VIEW_OPENER);
    }

    /**
     * Takes an arbitrary {@link CDOObject object} (including {@link CDOResourceNode resource nodes}) and returns {@link Match matches} for <b>all</b> elements of its {@link EObject#eAllContents() content tree}. This scope has the advantage that the comparison can
     * be rooted at specific objects that are different from (below of) the root resource. The disadvantage is that all the transitive children of this specific object are
     * matched, whether they differ or not. Major parts of huge repositories can be loaded to the client side easily, if no attention is paid.
     *
     * @since 4.3
     */
    public static AllContents create(CDOObject left, CDOView rightView, CDOView[] originView, CDOViewOpener viewOpener)
    {
      CDOView leftView = left.cdoView();
      CDOView view = openOriginView(leftView, rightView, originView, viewOpener);

      CDOObject right = CDOUtil.getCDOObject(rightView.getObject(left));
      CDOObject origin = view == null ? null : CDOUtil.getCDOObject(view.getObject(left));

      return new CDOComparisonScope.AllContents(left, right, origin);
    }
  }

  /**
   * Takes a {@link CDOView view}/{@link CDOTransaction transaction}
   * and returns {@link Match matches} only for the <b>changed</b> elements of the entire content tree of its {@link CDOView#getRootResource() root resource}.
   * The advantage of this scope is that CDO-specific mechanisms are used to efficiently (remotely) determine the set of changed objects. Only those and their container
   * objects are considered as matches, making this scope scale seamlessly with the overall size of a repository.
   * The following method returns comparisons that are based on this scope algorithm:
   * <ul>
   * <li>{@link CDOCompareUtil#compare(CDOView, CDOView, CDOView[])}
   * </ul>
   *
   * @author Eike Stepper
   */
  public static class Minimal extends CDOComparisonScope implements Predicate<EObject>
  {
    private Set<CDOID> ids;

    public Minimal(CDOView leftView, CDOView rightView, CDOView originView, Set<CDOID> ids)
    {
      super(getRoot(leftView), getRoot(rightView), getRoot(originView));
      this.ids = ids;

      Set<CDOID> requiredParentIDs = new HashSet<CDOID>();
      for (CDOID id : ids)
      {
        collectRequiredParentID(leftView, id, requiredParentIDs);
        collectRequiredParentID(rightView, id, requiredParentIDs);
        if (originView != null)
        {
          collectRequiredParentID(originView, id, requiredParentIDs);
        }
      }

      ids.addAll(requiredParentIDs);

      CDOResource rootResource = (CDOResource)getLeft();
      ids.remove(rootResource.cdoID());
    }

    public Iterator<? extends EObject> getChildren(EObject eObject)
    {
      return new AbstractTreeIterator<EObject>(eObject, false)
      {
        private static final long serialVersionUID = 1L;

        @Override
        public Iterator<EObject> getChildren(Object object)
        {
          if (object instanceof Resource)
          {
            Iterator<EObject> iterator = ((Resource)object).getContents().iterator();
            return Iterators.filter(iterator, Minimal.this);
          }

          Iterator<EObject> iterator = new ProperContentIterator<EObject>((EObject)object, isResolveProxies());
          return Iterators.filter(iterator, Minimal.this);
        }
      };
    }

    public boolean apply(EObject input)
    {
      CDOObject object = CDOUtil.getCDOObject(input);
      CDOID id = object.cdoID();
      return ids.contains(id);
    }

    private void collectRequiredParentIDs(CDOObject object, Set<CDOID> requiredParentIDs)
    {
      CDOState state = object.cdoState();
      if (state == CDOState.TRANSIENT)
      {
        return;
      }

      CDOView view = object.cdoView();
      if (state == CDOState.PROXY)
      {
        CDOUtil.load(object, view);
      }

      CDORevisionData revisionData = object.cdoRevision().data();

      CDOID resourceID = revisionData.getResourceID();
      if (!CDOIDUtil.isNull(resourceID))
      {
        collectRequiredParentIDs(view, resourceID, requiredParentIDs);
      }
      else
      {
        CDOID containerID;

        Object containerOrID = revisionData.getContainerID();
        if (containerOrID instanceof EObject)
        {
          containerID = (CDOID)((InternalCDOView)object.cdoView()).convertObjectToID(containerOrID);
        }
        else
        {
          containerID = (CDOID)containerOrID;
        }

        collectRequiredParentIDs(view, containerID, requiredParentIDs);
      }
    }

    private void collectRequiredParentIDs(CDOView view, CDOID id, Set<CDOID> requiredParentIDs)
    {
      if (!CDOIDUtil.isNull(id))
      {
        if (!ids.contains(id) && requiredParentIDs.add(id))
        {
          collectRequiredParentID(view, id, requiredParentIDs);
        }
      }
    }

    protected void collectRequiredParentID(CDOView view, CDOID id, Set<CDOID> requiredParentIDs)
    {
      try
      {
        CDOObject object = view.getObject(id);
        if (object != null)
        {
          collectRequiredParentIDs(object, requiredParentIDs);
        }
      }
      catch (ObjectNotFoundException ex)
      {
        //$FALL-THROUGH$
      }
    }

    public static IComparisonScope create(CDOView leftView, CDOView rightView, CDOView[] originView)
    {
      return create(leftView, rightView, originView, DEFAULT_VIEW_OPENER);
    }

    /**
     * @since 4.3
     */
    public static IComparisonScope create(CDOView leftView, CDOView rightView, CDOView[] originView,
        CDOViewOpener viewOpener)
    {
      CDOView view = openOriginView(leftView, rightView, originView, viewOpener);

      Set<CDOID> ids = getAffectedIDs(leftView, rightView, view);
      addDirtyIDs(ids, leftView);
      addDirtyIDs(ids, rightView);

      return new CDOComparisonScope.Minimal(leftView, rightView, view, ids);
    }

    public static IComparisonScope create(CDOView leftView, CDOView rightView, CDOView[] originView, Set<CDOID> ids)
    {
      return create(leftView, rightView, originView, ids, DEFAULT_VIEW_OPENER);
    }

    /**
     * @since 4.3
     */
    public static IComparisonScope create(CDOView leftView, CDOView rightView, CDOView[] originView, Set<CDOID> ids,
        CDOViewOpener viewOpener)
    {
      CDOView view = openOriginView(leftView, rightView, originView, viewOpener);
      return new CDOComparisonScope.Minimal(leftView, rightView, view, ids);
    }

    public static IComparisonScope create(CDOTransaction transaction)
    {
      return create(transaction, DEFAULT_VIEW_OPENER);
    }

    /**
     * @since 4.3
     */
    public static IComparisonScope create(CDOTransaction transaction, CDOViewOpener viewOpener)
    {
      if (viewOpener == null)
      {
        viewOpener = transaction.getSession();
      }

      CDOBranchPoint lastUpdate = transaction.getBranch().getPoint(transaction.getLastUpdateTime());
      CDOView lastView = viewOpener.openView(lastUpdate, new ResourceSetImpl());

      Set<CDOID> ids = new HashSet<CDOID>();
      ids.addAll(transaction.getNewObjects().keySet());
      ids.addAll(transaction.getDirtyObjects().keySet());
      ids.addAll(transaction.getDetachedObjects().keySet());

      return new CDOComparisonScope.Minimal(transaction, lastView, null, ids);
    }

    private static Set<CDOID> getAffectedIDs(CDOView leftView, CDOView rightView, CDOView originView)
    {
      if (originView != null)
      {
        InternalCDOSession session = (InternalCDOSession)leftView.getSession();
        MergeData mergeData = session.getMergeData(leftView, rightView, originView, false);
        return mergeData.getIDs();
      }

      CDOChangeSetData changeSetData = leftView.compareRevisions(rightView);
      return new HashSet<CDOID>(changeSetData.getChangeKinds().keySet());
    }

    private static void addDirtyIDs(Set<CDOID> ids, CDOView view)
    {
      if (view instanceof CDOTransaction)
      {
        CDOChangeSetData changeSetData = ((CDOTransaction)view).getChangeSetData();
        addDirtyIDs(ids, changeSetData.getNewObjects());
        addDirtyIDs(ids, changeSetData.getChangedObjects());
        addDirtyIDs(ids, changeSetData.getDetachedObjects());
      }
    }

    private static void addDirtyIDs(Set<CDOID> ids, List<? extends CDOIDAndVersion> keys)
    {
      for (CDOIDAndVersion key : keys)
      {
        ids.add(key.getID());
      }
    }

    private static CDOResource getRoot(CDOView view)
    {
      if (view == null)
      {
        return null;
      }

      return view.getRootResource();
    }
  }
}
