/*
 * Copyright (c) 2010-2012, 2014 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.internal.net4j.protocol;

import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;

import org.eclipse.net4j.util.om.monitor.EclipseMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;

import org.eclipse.core.runtime.NullProgressMonitor;

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @author Eike Stepper
 */
public class LoadMergeDataRequest extends CDOClientRequestWithMonitoring<Set<CDOID>>
{
  private CDORevisionAvailabilityInfo targetInfo;

  private CDORevisionAvailabilityInfo sourceInfo;

  private CDORevisionAvailabilityInfo targetBaseInfo;

  private CDORevisionAvailabilityInfo sourceBaseInfo;

  private int infos;

  public LoadMergeDataRequest(CDOClientProtocol protocol, CDORevisionAvailabilityInfo targetInfo,
      CDORevisionAvailabilityInfo sourceInfo, CDORevisionAvailabilityInfo targetBaseInfo,
      CDORevisionAvailabilityInfo sourceBaseInfo)
  {
    super(protocol, CDOProtocolConstants.SIGNAL_LOAD_MERGE_DATA);
    this.targetInfo = targetInfo;
    this.sourceInfo = sourceInfo;
    this.targetBaseInfo = targetBaseInfo;
    this.sourceBaseInfo = sourceBaseInfo;
    infos = 2 + (targetBaseInfo != null ? 1 : 0) + (sourceBaseInfo != null ? 1 : 0);
  }

  @Override
  protected void requesting(CDODataOutput out, OMMonitor monitor) throws IOException
  {
    if (monitor == null)
    {
      monitor = new EclipseMonitor(new NullProgressMonitor());
    }
    out.writeInt(infos);
    monitor.begin(infos);

    try
    {
      writeRevisionAvailabilityInfo(out, targetInfo, monitor.fork());
      writeRevisionAvailabilityInfo(out, sourceInfo, monitor.fork());

      if (infos > 2)
      {
        writeRevisionAvailabilityInfo(out, targetBaseInfo, monitor.fork());
      }

      if (infos > 3)
      {
        writeRevisionAvailabilityInfo(out, sourceBaseInfo, monitor.fork());
      }
    }
    finally
    {
      monitor.done();
    }
  }

  private void writeRevisionAvailabilityInfo(CDODataOutput out, CDORevisionAvailabilityInfo info, OMMonitor monitor)
      throws IOException
  {
    Set<CDOID> availableRevisions = info.getAvailableRevisions().keySet();
    int size = availableRevisions.size();

    out.writeCDOBranchPoint(info.getBranchPoint());
    out.writeInt(size);

    monitor.begin(size);

    try
    {
      for (CDOID id : availableRevisions)
      {
        out.writeCDOID(id);
        monitor.worked();
      }
    }
    finally
    {
      monitor.done();
    }
  }

  @Override
  protected Set<CDOID> confirming(CDODataInput in, OMMonitor monitor) throws IOException
  {
    if (monitor == null)
    {
      monitor = new EclipseMonitor(new NullProgressMonitor());
    }
    Set<CDOID> result = new HashSet<CDOID>();

    int size = in.readInt();
    monitor.begin(size + infos);

    try
    {
      for (int i = 0; i < size; i++)
      {
        CDOID id = in.readCDOID();
        result.add(id);
        monitor.worked();
      }

      readRevisionAvailabilityInfo(in, targetInfo, result, monitor.fork());
      readRevisionAvailabilityInfo(in, sourceInfo, result, monitor.fork());

      if (infos > 2)
      {
        readRevisionAvailabilityInfo(in, targetBaseInfo, result, monitor.fork());
      }

      if (infos > 3)
      {
        readRevisionAvailabilityInfo(in, sourceBaseInfo, result, monitor.fork());
      }

      return result;
    }
    finally
    {
      monitor.done();
    }
  }

  private void readRevisionAvailabilityInfo(CDODataInput in, CDORevisionAvailabilityInfo info, Set<CDOID> result,
      OMMonitor monitor) throws IOException
  {
    int size = in.readInt();
    monitor.begin(size + 1);

    try
    {
      for (int i = 0; i < size; i++)
      {
        CDORevision revision;
        if (in.readBoolean())
        {
          revision = in.readCDORevision();
        }
        else
        {
          CDORevisionKey key = in.readCDORevisionKey();
          revision = getRevision(key, targetInfo);

          if (revision == null && sourceInfo != null)
          {
            revision = getRevision(key, sourceInfo);
          }

          if (revision == null && targetBaseInfo != null)
          {
            revision = getRevision(key, targetBaseInfo);
          }

          if (revision == null)
          {
            throw new IllegalStateException("Missing revision: " + key);
          }
        }

        info.addRevision(revision);
        monitor.worked();
      }

      Set<Map.Entry<CDOID, CDORevisionKey>> entrySet = info.getAvailableRevisions().entrySet();
      for (Iterator<Map.Entry<CDOID, CDORevisionKey>> it = entrySet.iterator(); it.hasNext();)
      {
        Map.Entry<CDOID, CDORevisionKey> entry = it.next();
        if (!result.contains(entry.getKey()))
        {
          it.remove();
        }
      }

      monitor.worked();
    }
    finally
    {
      monitor.done();
    }
  }

  private CDORevision getRevision(CDORevisionKey key, CDORevisionAvailabilityInfo info)
  {
    CDORevisionKey revision = info.getRevision(key.getID());
    if (revision instanceof CDORevision)
    {
      if (key.equals(revision))
      {
        return (CDORevision)revision;
      }
    }

    return null;
  }
}
