/*
 * Copyright (c) 2012-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.spi.common.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.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.commit.CDOCommitData;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
import org.eclipse.emf.cdo.common.id.CDOIDReference;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.model.CDOType;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.CDOList;
import org.eclipse.emf.cdo.common.revision.CDORevisable;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.security.CDOPermissionProvider;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.internal.common.messages.Messages;
import org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOFeatureDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.revision.CDORevisionUnchunker;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;

import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.io.ExtendedDataOutput;
import org.eclipse.net4j.util.io.StringIO;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMapUtil;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * If the meaning of this type isn't clear, there really should be more of a description here...
 *
 * @author Eike Stepper
 * @since 4.2
 */
public class CDODataOutputImpl extends ExtendedDataOutput.Delegating implements CDODataOutput
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, CDODataOutputImpl.class);

  public CDODataOutputImpl(ExtendedDataOutput delegate)
  {
    super(delegate);
  }

  public void writeCDOPackageUnit(CDOPackageUnit packageUnit, boolean withPackages) throws IOException
  {
    ((InternalCDOPackageUnit)packageUnit).write(this, withPackages);
  }

  public void writeCDOPackageUnits(CDOPackageUnit... packageUnits) throws IOException
  {
    int size = packageUnits.length;
    writeInt(size);
    if (TRACER.isEnabled())
    {
      TRACER.format("Writing {0} package units", size); //$NON-NLS-1$
    }

    for (CDOPackageUnit packageUnit : packageUnits)
    {
      writeCDOPackageUnit(packageUnit, false);
    }
  }

  public void writeCDOPackageUnitType(CDOPackageUnit.Type type) throws IOException
  {
    writeByte(type.ordinal());
  }

  public void writeCDOPackageInfo(CDOPackageInfo packageInfo) throws IOException
  {
    ((InternalCDOPackageInfo)packageInfo).write(this);
  }

  public void writeCDOClassifierRef(CDOClassifierRef eClassifierRef) throws IOException
  {
    eClassifierRef.write(this);
  }

  public void writeCDOClassifierRef(EClassifier eClassifier) throws IOException
  {
    writeCDOClassifierRef(new CDOClassifierRef(eClassifier));
  }

  public void writeCDOPackageURI(String uri) throws IOException
  {
    getPackageURICompressor().write(this, uri);
  }

  public void writeCDOType(CDOType cdoType) throws IOException
  {
    ((CDOTypeImpl)cdoType).write(this);
  }

  public void writeCDOBranch(CDOBranch branch) throws IOException
  {
    writeInt(branch.getID());
  }

  public void writeCDOBranchPoint(CDOBranchPoint branchPoint) throws IOException
  {
    writeCDOBranch(branchPoint.getBranch());
    writeLong(branchPoint.getTimeStamp());
  }

  public void writeCDOBranchVersion(CDOBranchVersion branchVersion) throws IOException
  {
    writeCDOBranch(branchVersion.getBranch());
    writeInt(branchVersion.getVersion());
  }

  public void writeCDOChangeSetData(CDOChangeSetData changeSetData) throws IOException
  {
    Collection<CDOIDAndVersion> newObjects = changeSetData.getNewObjects();
    writeInt(newObjects.size());
    for (CDOIDAndVersion data : newObjects)
    {
      if (data instanceof CDORevision)
      {
        writeBoolean(true);
        writeCDORevision((CDORevision)data, CDORevision.UNCHUNKED);
      }
      else
      {
        writeBoolean(false);
        writeCDOIDAndVersion(data);
      }
    }

    Collection<CDORevisionKey> changedObjects = changeSetData.getChangedObjects();
    writeInt(changedObjects.size());
    for (CDORevisionKey data : changedObjects)
    {
      if (data instanceof CDORevisionDelta)
      {
        writeBoolean(true);
        writeCDORevisionDelta((CDORevisionDelta)data);
      }
      else
      {
        writeBoolean(false);
        writeCDORevisionKey(data);
      }
    }

    Collection<CDOIDAndVersion> detachedObjects = changeSetData.getDetachedObjects();
    writeInt(detachedObjects.size());
    for (CDOIDAndVersion data : detachedObjects)
    {
      writeCDOID(data.getID());
      boolean isCDORevisionKey = data instanceof CDORevisionKey;
      int version = data.getVersion();
      writeInt(version);
      writeBoolean(isCDORevisionKey);
      if (isCDORevisionKey)
      {
        CDORevisionKey revisionKey = (CDORevisionKey)data;
        writeCDOBranch(revisionKey.getBranch());
      }
    }
  }

  public void writeCDOCommitData(CDOCommitData commitData) throws IOException
  {
    Collection<CDOPackageUnit> newPackageUnits = commitData.getNewPackageUnits();
    writeInt(newPackageUnits.size());
    for (CDOPackageUnit data : newPackageUnits)
    {
      writeCDOPackageUnit(data, false);
    }

    writeCDOChangeSetData(commitData);
  }

  public void writeCDOCommitInfo(CDOCommitInfo commitInfo) throws IOException
  {
    writeLong(commitInfo.getTimeStamp());
    writeLong(commitInfo.getPreviousTimeStamp());

    CDOBranch branch = commitInfo.getBranch();
    if (branch != null)
    {
      writeBoolean(true);
      writeCDOBranch(branch);
      writeString(commitInfo.getUserID());
      writeString(commitInfo.getComment());
      writeCDOCommitData(commitInfo);
    }
    else
    {
      // FailureCommitInfo
      writeBoolean(false);
    }
  }

  public void writeCDOLockChangeInfo(CDOLockChangeInfo lockChangeInfo) throws IOException
  {
    if (lockChangeInfo.isInvalidateAll())
    {
      writeBoolean(true);
    }
    else
    {
      writeBoolean(false);
      writeCDOBranchPoint(lockChangeInfo);
      writeCDOLockOwner(lockChangeInfo.getLockOwner());
      writeEnum(lockChangeInfo.getOperation());
      writeCDOLockType(lockChangeInfo.getLockType());

      CDOLockState[] lockStates = lockChangeInfo.getLockStates();
      writeInt(lockStates.length);
      for (CDOLockState lockState : lockStates)
      {
        writeCDOLockState(lockState);
      }
    }
  }

  public void writeCDOLockArea(LockArea lockArea) throws IOException
  {
    writeString(lockArea.getDurableLockingID());
    writeCDOBranch(lockArea.getBranch());
    writeLong(lockArea.getTimeStamp());
    writeString(lockArea.getUserID());
    writeBoolean(lockArea.isReadOnly());

    writeInt(lockArea.getLocks().size());
    for (Map.Entry<CDOID, LockGrade> entry : lockArea.getLocks().entrySet())
    {
      writeCDOID(entry.getKey());
      writeEnum(entry.getValue());
    }
  }

  public void writeCDOLockOwner(CDOLockOwner lockOwner) throws IOException
  {
    writeInt(lockOwner.getSessionID());
    writeInt(lockOwner.getViewID());
    writeString(lockOwner.getDurableLockingID());
    writeBoolean(lockOwner.isDurableView());
  }

  public void writeCDOLockState(CDOLockState lockState) throws IOException
  {
    Object o = lockState.getLockedObject();
    if (o instanceof CDOID)
    {
      writeBoolean(false);
      writeCDOID((CDOID)o);
    }
    else if (o instanceof CDOIDAndBranch)
    {
      writeBoolean(true);
      writeCDOIDAndBranch((CDOIDAndBranch)o);
    }
    else
    {
      throw new AssertionError("Unexpected type: " + o.getClass().getSimpleName());
    }

    Set<CDOLockOwner> readLockOwners = lockState.getReadLockOwners();
    writeInt(readLockOwners.size());
    for (CDOLockOwner readLockOwner : readLockOwners)
    {
      writeCDOLockOwner(readLockOwner);
    }

    CDOLockOwner writeLockOwner = lockState.getWriteLockOwner();
    if (writeLockOwner != null)
    {
      writeBoolean(true);
      writeCDOLockOwner(writeLockOwner);
    }
    else
    {
      writeBoolean(false);
    }

    CDOLockOwner writeOptionOwner = lockState.getWriteOptionOwner();
    if (writeOptionOwner != null)
    {
      writeBoolean(true);
      writeCDOLockOwner(writeOptionOwner);
    }
    else
    {
      writeBoolean(false);
    }
  }

  public void writeCDOLockType(LockType lockType) throws IOException
  {
    writeEnum(lockType);
  }

  public void writeCDOID(CDOID id) throws IOException
  {
    CDOIDUtil.write(this, id);
  }

  public void writeCDOIDReference(CDOIDReference idReference) throws IOException
  {
    idReference.write(this);
  }

  public void writeCDOIDAndVersion(CDOIDAndVersion idAndVersion) throws IOException
  {
    writeCDOID(idAndVersion.getID());
    writeInt(idAndVersion.getVersion());
  }

  public void writeCDOIDAndBranch(CDOIDAndBranch idAndBranch) throws IOException
  {
    writeCDOID(idAndBranch.getID());
    writeCDOBranch(idAndBranch.getBranch());
  }

  public void writeCDORevisionKey(CDORevisionKey revisionKey) throws IOException
  {
    writeCDOID(revisionKey.getID());
    writeCDOBranch(revisionKey.getBranch());
    writeInt(revisionKey.getVersion());
  }

  public void writeCDORevision(CDORevision revision, int referenceChunk) throws IOException
  {
    writeCDORevision(revision, referenceChunk, null);
  }

  public void writeCDORevision(CDORevision revision, int referenceChunk, CDOBranchPoint securityContext)
      throws IOException
  {
    if (revision != null)
    {
      writeBoolean(true);
      ((InternalCDORevision)revision).write(this, referenceChunk, securityContext);
    }
    else
    {
      writeBoolean(false);
    }
  }

  public void writeCDORevisable(CDORevisable revisable) throws IOException
  {
    writeCDOBranch(revisable.getBranch());
    writeInt(revisable.getVersion());
    writeLong(revisable.getTimeStamp());
    writeLong(revisable.getRevised());
  }

  public void writeCDOList(EClass owner, EStructuralFeature feature, CDOList list, int referenceChunk)
      throws IOException
  {
    // TODO Simon: Could most of this stuff be moved into the list?
    // (only if protected methods of this class don't need to become public)
    int size = list == null ? 0 : list.size();
    if (size > 0)
    {
      // Need to adjust the referenceChunk in case where we do not have enough value in the list.
      // Even if the referenceChunk is specified, a provider of data could have override that value.
      int sizeToLook = referenceChunk == CDORevision.UNCHUNKED ? size : Math.min(referenceChunk, size);
      for (int i = 0; i < sizeToLook; i++)
      {
        Object element = list.get(i, false);
        if (element == CDORevisionUtil.UNINITIALIZED)
        {
          referenceChunk = i;
          break;
        }
      }
    }

    if (referenceChunk != CDORevision.UNCHUNKED && referenceChunk < size)
    {
      // This happens only on server-side
      if (TRACER.isEnabled())
      {
        TRACER.format("Writing feature {0}: size={1}, referenceChunk={2}", feature.getName(), size, referenceChunk); //$NON-NLS-1$
      }

      writeInt(-size);
      writeInt(referenceChunk);
      size = referenceChunk;
    }
    else
    {
      if (TRACER.isEnabled())
      {
        TRACER.format("Writing feature {0}: size={1}", feature.getName(), size); //$NON-NLS-1$
      }

      writeInt(size);
    }

    CDOIDProvider idProvider = getIDProvider();
    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
    for (int j = 0; j < size; j++)
    {
      Object value = list.get(j, false);
      EStructuralFeature innerFeature = feature; // Prepare for possible feature map
      if (isFeatureMap)
      {
        FeatureMap.Entry entry = (FeatureMap.Entry)value;
        innerFeature = entry.getEStructuralFeature();
        value = entry.getValue();

        EClass eClass = innerFeature.getEContainingClass();
        EPackage ePackage = eClass.getEPackage();
        if (ePackage.getName() == null)
        {
          // Probably a demand-created DocumentRoot feature
          writeBoolean(true);
          writeString(ePackage.getNsURI());
          writeString(eClass.getName());
          writeBoolean(innerFeature instanceof EReference);
          writeString(innerFeature.getName());
        }
        else
        {
          writeBoolean(false);
          writeCDOClassifierRef(eClass);

          int featureID = eClass.getFeatureID(innerFeature);
          writeInt(featureID);
        }
      }

      if (value != null && innerFeature instanceof EReference)
      {
        value = idProvider.provideCDOID(value);
      }

      if (TRACER.isEnabled())
      {
        TRACER.trace("    " + value); //$NON-NLS-1$
      }

      writeCDOFeatureValue(innerFeature, value);
    }
  }

  public void writeCDOFeatureValue(EStructuralFeature feature, Object value) throws IOException
  {
    CDOType type = CDOModelUtil.getType(feature);
    type.writeValue(this, value);
  }

  public void writeCDORevisionDelta(CDORevisionDelta revisionDelta) throws IOException
  {
    ((CDORevisionDeltaImpl)revisionDelta).write(this);
  }

  public void writeCDOFeatureDelta(EClass owner, CDOFeatureDelta featureDelta) throws IOException
  {
    ((CDOFeatureDeltaImpl)featureDelta).write(this, owner);
  }

  public void writeCDORevisionOrPrimitive(Object value) throws IOException
  {
    // Value conversions
    if (value == null)
    {
      value = CDOID.NULL;
    }
    else if (value instanceof EObject)
    {
      value = getIDProvider().provideCDOID(value);
    }
    else if (value instanceof CDORevision)
    {
      value = ((CDORevision)value).getID();
    }

    // Type determination
    CDOType type = null;
    if (value instanceof CDOID)
    {
      type = CDOType.OBJECT;
    }
    else if (value instanceof Throwable)
    {
      type = CDOType.EXCEPTION;
    }
    else
    {
      type = CDOModelUtil.getPrimitiveType(value.getClass());
      if (type == null)
      {
        throw new IllegalArgumentException(
            MessageFormat.format(Messages.getString("CDODataOutputImpl.6"), value.getClass())); //$NON-NLS-1$
      }
    }

    writeCDOType(type);
    type.writeValue(this, value);
  }

  public void writeCDORevisionOrPrimitiveOrClassifier(Object value) throws IOException
  {
    if (value instanceof EClassifier)
    {
      writeBoolean(true);
      writeCDOClassifierRef((EClass)value);
    }
    else
    {
      writeBoolean(false);
      writeCDORevisionOrPrimitive(value);
    }
  }

  public CDOPackageRegistry getPackageRegistry()
  {
    return null;
  }

  public CDOIDProvider getIDProvider()
  {
    return null;
  }

  public CDOPermissionProvider getPermissionProvider()
  {
    return CDORevision.PERMISSION_PROVIDER;
  }

  /**
   * @since 4.3
   */
  public CDORevisionUnchunker getRevisionUnchunker()
  {
    return null;
  }

  protected StringIO getPackageURICompressor()
  {
    return StringIO.DIRECT;
  }
}
