/*
 * Copyright (c) 2009-2013 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 213402
 *    Andre Dietisheim - bug 256649
 */
package org.eclipse.emf.cdo.server.internal.net4j.protocol;

import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDReference;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.common.security.CDOPermission;
import org.eclipse.emf.cdo.etypes.EtypesPackage;
import org.eclipse.emf.cdo.server.IPermissionManager;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
import org.eclipse.emf.cdo.spi.server.InternalSession;
import org.eclipse.emf.cdo.spi.server.InternalTransaction;
import org.eclipse.emf.cdo.spi.server.InternalView;

import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
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.xmi.impl.EcoreResourceFactoryImpl;

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author Eike Stepper
 */
public class CommitTransactionIndication extends CDOServerIndicationWithMonitoring
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, CommitTransactionIndication.class);

  protected InternalCommitContext commitContext;

  public CommitTransactionIndication(CDOServerProtocol protocol)
  {
    super(protocol, CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION);
  }

  protected CommitTransactionIndication(CDOServerProtocol protocol, short signalID)
  {
    super(protocol, signalID);
  }

  @Override
  protected InternalCDOPackageRegistry getPackageRegistry()
  {
    return commitContext.getPackageRegistry();
  }

  protected void initializeCommitContext(CDODataInput in) throws Exception
  {
    int viewID = in.readInt();
    commitContext = getTransaction(viewID).createCommitContext();
  }

  @Override
  protected void indicating(CDODataInput in, OMMonitor monitor) throws Exception
  {
    try
    {
      monitor.begin(OMMonitor.TEN);
      indicatingRead(in, monitor.fork(OMMonitor.ONE));
      indicatingCommit(in, monitor.fork(OMMonitor.TEN - OMMonitor.ONE));
    }
    catch (IOException ex)
    {
      throw ex;
    }
    catch (Exception ex)
    {
      OM.LOG.error(ex);
      throw WrappedException.wrap(ex);
    }
    finally
    {
      monitor.done();
    }
  }

  protected void indicatingRead(CDODataInput in, OMMonitor monitor) throws Exception
  {
    // Create commit context
    initializeCommitContext(in);
    commitContext.preWrite();

    long lastUpdateTime = in.readLong();
    boolean autoReleaseLocksEnabled = in.readBoolean();
    String commitComment = in.readString();

    InternalCDOPackageUnit[] newPackageUnits = new InternalCDOPackageUnit[in.readInt()];
    CDOLockState[] locksOnNewObjects = new CDOLockState[in.readInt()];
    InternalCDORevision[] newObjects = new InternalCDORevision[in.readInt()];
    InternalCDORevisionDelta[] dirtyObjectDeltas = new InternalCDORevisionDelta[in.readInt()];
    CDOID[] detachedObjects = new CDOID[in.readInt()];
    monitor.begin(newPackageUnits.length + newObjects.length + dirtyObjectDeltas.length + detachedObjects.length);

    try
    {
      // New package units
      if (TRACER.isEnabled())
      {
        TRACER.format("Reading {0} new package units", newPackageUnits.length); //$NON-NLS-1$
      }

      if (newPackageUnits.length != 0)
      {
        InternalCDOPackageRegistry packageRegistry = commitContext.getPackageRegistry();
        ResourceSet resourceSet = createResourceSet(packageRegistry);
        for (int i = 0; i < newPackageUnits.length; i++)
        {
          newPackageUnits[i] = (InternalCDOPackageUnit)in.readCDOPackageUnit(resourceSet);
          packageRegistry.putPackageUnit(newPackageUnits[i]); // Must happen before readCDORevision!!!
          monitor.worked();
        }

        // When all packages are deserialized and registered, resolve them
        // Note: EcoreUtil.resolveAll(resourceSet) does *not* do the trick
        EMFUtil.safeResolveAll(resourceSet);
      }

      // Locks on new objects
      if (TRACER.isEnabled())
      {
        TRACER.format("Reading {0} locks on new objects", locksOnNewObjects.length); //$NON-NLS-1$
      }

      for (int i = 0; i < locksOnNewObjects.length; i++)
      {
        locksOnNewObjects[i] = in.readCDOLockState();
        monitor.worked();
      }

      // New objects
      if (TRACER.isEnabled())
      {
        TRACER.format("Reading {0} new objects", newObjects.length); //$NON-NLS-1$
      }

      boolean usingEcore = false;
      boolean usingEtypes = false;
      for (int i = 0; i < newObjects.length; i++)
      {
        newObjects[i] = (InternalCDORevision)in.readCDORevision();

        EPackage ePackage = newObjects[i].getEClass().getEPackage();
        if (ePackage == EcorePackage.eINSTANCE)
        {
          usingEcore = true;
        }
        else if (ePackage == EtypesPackage.eINSTANCE)
        {
          usingEtypes = true;
        }

        monitor.worked();
      }

      // Make the assignment of permanent IDs predictable
      Arrays.sort(newObjects, new Comparator<InternalCDORevision>()
      {
        public int compare(InternalCDORevision r1, InternalCDORevision r2)
        {
          return r1.getID().compareTo(r2.getID());
        }
      });

      // Dirty objects
      if (TRACER.isEnabled())
      {
        TRACER.format("Reading {0} dirty object deltas", dirtyObjectDeltas.length); //$NON-NLS-1$
      }

      for (int i = 0; i < dirtyObjectDeltas.length; i++)
      {
        dirtyObjectDeltas[i] = (InternalCDORevisionDelta)in.readCDORevisionDelta();
        monitor.worked();
      }

      boolean clearResourcePathCache = in.readBoolean();
      boolean auditing = getRepository().isSupportingAudits();
      boolean ensuringReferentialIntegrity = getRepository().isEnsuringReferentialIntegrity();

      Map<CDOID, EClass> detachedObjectTypes = null;
      if (auditing || ensuringReferentialIntegrity)
      {
        detachedObjectTypes = CDOIDUtil.createMap();
      }

      CDOBranchVersion[] detachedObjectVersions = null;
      if (auditing && detachedObjects.length != 0)
      {
        detachedObjectVersions = new CDOBranchVersion[detachedObjects.length];
      }

      CDOBranch transactionBranch = commitContext.getBranchPoint().getBranch();
      for (int i = 0; i < detachedObjects.length; i++)
      {
        CDOID id = in.readCDOID();
        detachedObjects[i] = id;

        if (detachedObjectTypes != null)
        {
          EClass eClass = (EClass)in.readCDOClassifierRefAndResolve();
          detachedObjectTypes.put(id, eClass);
        }

        if (detachedObjectVersions != null)
        {
          CDOBranch branch;
          int version = in.readInt();
          if (version < 0)
          {
            version = -version;
            branch = in.readCDOBranch();
          }
          else
          {
            branch = transactionBranch;
          }

          detachedObjectVersions[i] = branch.getVersion(version);
        }

        monitor.worked();
      }

      if (detachedObjectTypes != null && detachedObjectTypes.isEmpty())
      {
        detachedObjectTypes = null;
      }

      commitContext.setLastUpdateTime(lastUpdateTime);
      commitContext.setAutoReleaseLocksEnabled(autoReleaseLocksEnabled);
      commitContext.setClearResourcePathCache(clearResourcePathCache);
      commitContext.setUsingEcore(usingEcore);
      commitContext.setUsingEtypes(usingEtypes);
      commitContext.setNewPackageUnits(newPackageUnits);
      commitContext.setLocksOnNewObjects(locksOnNewObjects);
      commitContext.setNewObjects(newObjects);
      commitContext.setDirtyObjectDeltas(dirtyObjectDeltas);
      commitContext.setDetachedObjects(detachedObjects);
      commitContext.setDetachedObjectTypes(detachedObjectTypes);
      commitContext.setDetachedObjectVersions(detachedObjectVersions);
      commitContext.setCommitComment(commitComment);
      commitContext.setLobs(getIndicationStream());
    }
    finally
    {
      monitor.done();
    }
  }

  protected void indicatingCommit(CDODataInput in, OMMonitor monitor)
  {
    getRepository().commit(commitContext, monitor);
  }

  @Override
  protected void indicatingFailed()
  {
    if (commitContext != null)
    {
      commitContext.postCommit(false);
      commitContext = null;
    }
  }

  @Override
  protected void responding(CDODataOutput out, OMMonitor monitor) throws Exception
  {
    boolean success = false;

    try
    {
      byte rollbackReason = commitContext.getRollbackReason();
      String rollbackMessage = commitContext.getRollbackMessage();
      List<CDOIDReference> xRefs = commitContext.getXRefs();

      success = respondingException(out, rollbackReason, rollbackMessage, xRefs);
      if (success)
      {
        respondingResult(out);
        respondingMappingNewObjects(out);
        respondingNewLockStates(out);
        respondingNewPermissions(out);
      }
    }
    finally
    {
      commitContext.postCommit(success);
    }
  }

  protected boolean respondingException(CDODataOutput out, byte rollbackReason, String rollbackMessage,
      List<CDOIDReference> xRefs) throws Exception
  {
    boolean success = rollbackMessage == null;
    out.writeBoolean(success);
    if (!success)
    {
      out.writeByte(rollbackReason);
      out.writeString(rollbackMessage);
      out.writeCDOBranchPoint(commitContext.getBranchPoint());
      out.writeLong(commitContext.getPreviousTimeStamp());

      if (xRefs != null)
      {
        out.writeInt(xRefs.size());
        for (CDOIDReference xRef : xRefs)
        {
          out.writeCDOIDReference(xRef);
        }
      }
      else
      {
        out.writeInt(0);
      }
    }

    return success;
  }

  protected void respondingResult(CDODataOutput out) throws Exception
  {
    out.writeCDOBranchPoint(commitContext.getBranchPoint());
    out.writeLong(commitContext.getPreviousTimeStamp());
    out.writeByte(commitContext.getSecurityImpact());
  }

  protected void respondingMappingNewObjects(CDODataOutput out) throws Exception
  {
    Map<CDOID, CDOID> idMappings = commitContext.getIDMappings();
    for (Entry<CDOID, CDOID> entry : idMappings.entrySet())
    {
      CDOID oldID = entry.getKey();
      CDOID newID = entry.getValue();
      out.writeCDOID(oldID);
      out.writeCDOID(newID);
    }

    out.writeCDOID(CDOID.NULL);
  }

  protected void respondingNewLockStates(CDODataOutput out) throws Exception
  {
    List<LockState<Object, IView>> newLockStates = commitContext.getPostCommmitLockStates();
    if (newLockStates != null)
    {
      out.writeInt(newLockStates.size());
      for (LockState<Object, IView> lockState : newLockStates)
      {
        CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState);
        out.writeCDOLockState(cdoLockState);
      }
    }
    else
    {
      out.writeInt(0);
    }
  }

  protected void respondingNewPermissions(CDODataOutput out) throws Exception
  {
    InternalSession session = getSession();
    IPermissionManager permissionManager = session.getManager().getPermissionManager();
    if (permissionManager != null)
    {
      if (commitContext.getSecurityImpact() != CommitNotificationInfo.IMPACT_REALM)
      {
        out.writeBoolean(true);

        InternalCDORevision[] newObjects = commitContext.getNewObjects();
        InternalCDORevision[] dirtyObjects = commitContext.getDirtyObjects();

        out.writeInt(newObjects.length + dirtyObjects.length);
        respondingNewPermissions(out, permissionManager, session, newObjects);
        respondingNewPermissions(out, permissionManager, session, dirtyObjects);

        return;
      }
    }

    out.writeBoolean(false);
  }

  protected void respondingNewPermissions(CDODataOutput out, IPermissionManager permissionManager,
      InternalSession session, InternalCDORevision[] revisions) throws Exception
  {
    int size = revisions.length;
    if (size != 0)
    {
      CDOBranchPoint securityContext = commitContext.getBranchPoint();
      for (int i = 0; i < size; i++)
      {
        InternalCDORevision revision = revisions[i];
        CDOPermission permission = permissionManager.getPermission(revision, securityContext, session);

        out.writeCDOID(revision.getID());
        out.writeEnum(permission);
      }
    }
  }

  protected InternalTransaction getTransaction(int viewID)
  {
    InternalView view = getSession().getView(viewID);
    if (view instanceof InternalTransaction)
    {
      return (InternalTransaction)view;
    }

    throw new IllegalStateException("Illegal transaction: " + view); //$NON-NLS-1$
  }

  private ResourceSet createResourceSet(InternalCDOPackageRegistry packageRegistry)
  {
    ResourceSet resourceSet = new ResourceSetImpl()
    {
      @Override
      protected void demandLoad(Resource resource) throws IOException
      {
        // Do nothing: we don't want this ResourceSet to attempt demand-loads.
      }
    };

    Resource.Factory resourceFactory = new EcoreResourceFactoryImpl();
    resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", resourceFactory); //$NON-NLS-1$
    resourceSet.setPackageRegistry(packageRegistry);
    return resourceSet;
  }
}
