/*
 * Copyright (c) 2010-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.internal.server.syncing;

import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.CDOCommonRepository.State;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchChangedEvent;
import org.eclipse.emf.cdo.common.branch.CDOBranchChangedEvent.ChangeKind;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.internal.common.revision.NOOPRevisionCache;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
import org.eclipse.emf.cdo.server.StoreThreadLocal;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionConfiguration;
import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchAdjustable;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
import org.eclipse.emf.cdo.spi.server.InternalRepositorySynchronizer;
import org.eclipse.emf.cdo.spi.server.InternalSynchronizableRepository;

import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
import org.eclipse.net4j.util.concurrent.PriorityQueueRunnable;
import org.eclipse.net4j.util.concurrent.PriorityQueueRunner;
import org.eclipse.net4j.util.container.IContainerDelta;
import org.eclipse.net4j.util.container.SingleDeltaContainerEvent;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.lifecycle.ILifecycleEvent;
import org.eclipse.net4j.util.om.monitor.NotifyingMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
import org.eclipse.emf.spi.cdo.InternalCDOSession;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author Eike Stepper
 * @since 3.0
 */
public class RepositorySynchronizer extends PriorityQueueRunner implements InternalRepositorySynchronizer
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REPOSITORY, RepositorySynchronizer.class);

  private static final Integer CONNECT_PRIORITY = 0;

  private static final Integer REPLICATE_PRIORITY = 1;

  private static final Integer BRANCH_PRIORITY = 2;

  private static final Integer COMMIT_PRIORITY = 3;

  private static final Integer LOCKS_PRIORITY = COMMIT_PRIORITY;

  private int retryInterval = DEFAULT_RETRY_INTERVAL;

  private Object connectLock = new Object();

  private InternalSynchronizableRepository localRepository;

  /**
   * The session that connects to the master; used passively to receive notifications, and actively to request
   * replications.
   */
  private InternalCDOSession remoteSession;

  private RemoteSessionListener remoteSessionListener = new RemoteSessionListener();

  private CDOSessionConfigurationFactory remoteSessionConfigurationFactory;

  private boolean rawReplication = true;

  private int maxRecommits = DEFAULT_MAX_RECOMMITS;

  private int recommitInterval = DEFAULT_RECOMMIT_INTERVAL;

  private Timer recommitTimer;

  public RepositorySynchronizer()
  {
    setDaemon(true);
  }

  public int getRetryInterval()
  {
    return retryInterval;
  }

  public void setRetryInterval(int retryInterval)
  {
    this.retryInterval = retryInterval;
  }

  public InternalSynchronizableRepository getLocalRepository()
  {
    return localRepository;
  }

  public void setLocalRepository(InternalSynchronizableRepository localRepository)
  {
    checkInactive();
    this.localRepository = localRepository;
  }

  public CDOSessionConfigurationFactory getRemoteSessionConfigurationFactory()
  {
    return remoteSessionConfigurationFactory;
  }

  public void setRemoteSessionConfigurationFactory(CDOSessionConfigurationFactory masterSessionConfigurationFactory)
  {
    checkArg(masterSessionConfigurationFactory, "remoteSessionConfigurationFactory"); //$NON-NLS-1$
    remoteSessionConfigurationFactory = masterSessionConfigurationFactory;
  }

  public InternalCDOSession getRemoteSession()
  {
    return remoteSession;
  }

  public boolean isRawReplication()
  {
    return rawReplication;
  }

  public void setRawReplication(boolean rawReplication)
  {
    checkInactive();
    this.rawReplication = rawReplication;
  }

  public int getMaxRecommits()
  {
    return maxRecommits;
  }

  public void setMaxRecommits(int maxRecommits)
  {
    this.maxRecommits = maxRecommits;
  }

  public int getRecommitInterval()
  {
    return recommitInterval;
  }

  public void setRecommitInterval(int recommitInterval)
  {
    this.recommitInterval = recommitInterval;
  }

  public boolean isEmpty()
  {
    return remoteSession == null;
  }

  public CDOSession[] getElements()
  {
    if (remoteSession == null)
    {
      return new CDOSession[0];
    }

    return new CDOSession[] { remoteSession };
  }

  @Override
  protected String getThreadName()
  {
    return "CDORepositorySynchronizer"; //$NON-NLS-1$
  }

  @Override
  protected void noWork(WorkContext context)
  {
    if (!localRepository.isActive())
    {
      context.terminate();
    }
  }

  @Override
  protected void doBeforeActivate() throws Exception
  {
    super.doBeforeActivate();
    checkState(remoteSessionConfigurationFactory, "remoteSessionConfigurationFactory"); //$NON-NLS-1$
    checkState(localRepository, "localRepository"); //$NON-NLS-1$
  }

  @Override
  protected void doAfterActivate() throws Exception
  {
    super.doAfterActivate();
    scheduleConnect();
  }

  @Override
  protected void doDeactivate() throws Exception
  {
    if (recommitTimer != null)
    {
      recommitTimer.cancel();
      recommitTimer = null;
    }

    if (remoteSession != null)
    {
      closeRemoteSession();
    }

    super.doDeactivate();
  }

  protected void handleConnect()
  {
    scheduleReplicate();

    remoteSession.addListener(remoteSessionListener);
    remoteSession.getBranchManager().addListener(remoteSessionListener);

    fireEvent(new SingleDeltaContainerEvent<CDOSession>(this, remoteSession, IContainerDelta.Kind.ADDED));
  }

  protected void handleDisconnect()
  {
    if (TRACER.isEnabled())
    {
      TRACER.trace("Disconnected from master."); //$NON-NLS-1$
    }

    if (localRepository.hasBeenReplicated())
    {
      localRepository.setState(CDOCommonRepository.State.OFFLINE);
    }
    else
    {
      localRepository.setState(CDOCommonRepository.State.INITIAL);
    }

    if (remoteSession != null)
    {
      CDOSession element = remoteSession;
      closeRemoteSession();
      fireEvent(new SingleDeltaContainerEvent<CDOSession>(this, element, IContainerDelta.Kind.REMOVED));
    }

    reconnect();
  }

  private void closeRemoteSession()
  {
    remoteSession.removeListener(remoteSessionListener);
    remoteSession.getBranchManager().removeListener(remoteSessionListener);
    remoteSession.close();
    remoteSession = null;
  }

  private void reconnect()
  {
    clearQueue();
    if (isActive())
    {
      scheduleConnect();
    }
  }

  private void scheduleConnect()
  {
    synchronized (connectLock)
    {
      State state = localRepository.getState();
      if (state.isConnected())
      {
        return;
      }

      if (isActive())
      {
        addWork(new ConnectRunnable());
      }
    }
  }

  private void scheduleReplicate()
  {
    if (isActive())
    {
      addWork(new ReplicateRunnable());
    }
  }

  private void sleepRetryInterval()
  {
    long end = System.currentTimeMillis() + 1000L * retryInterval;

    for (;;)
    {
      long now = System.currentTimeMillis();
      if (now >= end || !isActive())
      {
        break;
      }

      ConcurrencyUtil.sleep(Math.min(100L, end - now));
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class RemoteSessionListener implements IListener
  {
    public void notifyEvent(IEvent event)
    {
      if (!isActive())
      {
        return;
      }

      if (event instanceof CDOBranchChangedEvent)
      {
        CDOBranchChangedEvent e = (CDOBranchChangedEvent)event;
        if (e.getChangeKind() == ChangeKind.CREATED)
        {
          addWork(new BranchRunnable(e.getBranch()));
        }
        else
        {
          throw new UnsupportedOperationException("Branch renaming not supported: " + RepositorySynchronizer.this);
        }
      }
      else if (event instanceof CDOSessionInvalidationEvent)
      {
        CDOSessionInvalidationEvent e = (CDOSessionInvalidationEvent)event;
        if (e.isRemote())
        {
          addWork(new CommitRunnable(e));
        }
      }
      else if (event instanceof CDOSessionLocksChangedEvent)
      {
        CDOSessionLocksChangedEvent e = (CDOSessionLocksChangedEvent)event;
        addWork(new LocksRunnable(e));
      }
      else if (event instanceof ILifecycleEvent)
      {
        ILifecycleEvent e = (ILifecycleEvent)event;
        if (e.getKind() == ILifecycleEvent.Kind.DEACTIVATED && e.getSource() == remoteSession)
        {
          handleDisconnect();
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class ConnectRunnable extends PriorityQueueRunnable
  {
    public ConnectRunnable()
    {
    }

    public void run()
    {
      synchronized (connectLock)
      {
        checkActive();
        if (TRACER.isEnabled())
        {
          TRACER.trace("Connecting to master..."); //$NON-NLS-1$
        }

        try
        {
          CDOSessionConfiguration masterConfiguration = remoteSessionConfigurationFactory.createSessionConfiguration();
          masterConfiguration.setPassiveUpdateMode(PassiveUpdateMode.ADDITIONS);
          masterConfiguration.setLockNotificationMode(LockNotificationMode.ALWAYS);

          remoteSession = (InternalCDOSession)masterConfiguration.openSession();

          ensureNOOPRevisionCache();
        }
        catch (Exception ex)
        {
          remoteSession = null;

          if (isActive())
          {
            if (TRACER.isEnabled())
            {
              TRACER.format("Connection attempt failed. Retrying in {0} seconds...", retryInterval); //$NON-NLS-1$
            }

            fireThrowable(ex);
            sleepRetryInterval();
            reconnect();
          }

          return;
        }

        if (TRACER.isEnabled())
        {
          TRACER.trace("Connected to master."); //$NON-NLS-1$
        }

        handleConnect();
      }
    }

    @Override
    protected Integer getPriority()
    {
      return CONNECT_PRIORITY;
    }

    private void ensureNOOPRevisionCache()
    {
      // Ensure that incoming revisions are not cached!
      InternalCDORevisionCache cache = remoteSession.getRevisionManager().getCache();
      if (!(cache instanceof NOOPRevisionCache))
      {
        String message = "Master session does not use a NOOPRevisionCache: " + cache.getClass().getName();
        OM.LOG.error(message);
        throw new Error(message);
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class ReplicateRunnable extends PriorityQueueRunnable
  {
    public ReplicateRunnable()
    {
    }

    public void run()
    {
      try
      {
        checkActive();
        if (TRACER.isEnabled())
        {
          TRACER.trace("Synchronizing with master..."); //$NON-NLS-1$
        }

        boolean firstSyncing = !localRepository.hasBeenReplicated();
        if (!firstSyncing)
        {
          localRepository.setState(CDOCommonRepository.State.SYNCING);
        }

        CDOSessionProtocol sessionProtocol = remoteSession.getSessionProtocol();
        OMMonitor monitor = new NotifyingMonitor("Synchronizing", getListeners());

        if (isRawReplication())
        {
          sessionProtocol.replicateRepositoryRaw(localRepository, monitor);
        }
        else
        {
          sessionProtocol.replicateRepository(localRepository, monitor);
        }

        if (firstSyncing)
        {
          CDOID id = remoteSession.getRepositoryInfo().getRootResourceID();
          localRepository.setRootResourceID(id);
        }

        localRepository.setState(CDOCommonRepository.State.ONLINE);
        if (TRACER.isEnabled())
        {
          TRACER.trace("Synchronized with master."); //$NON-NLS-1$
        }
      }
      catch (RuntimeException ex)
      {
        if (isActive())
        {
          if (TRACER.isEnabled())
          {
            TRACER.format("Replication attempt failed. Retrying in {0} seconds...", ex, retryInterval); //$NON-NLS-1$
          }

          fireThrowable(ex);
          sleepRetryInterval();
          handleDisconnect();
        }
      }
    }

    @Override
    protected Integer getPriority()
    {
      return REPLICATE_PRIORITY;
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class BranchRunnable extends PriorityQueueRunnable
  {
    private CDOBranch branch;

    public BranchRunnable(CDOBranch branch)
    {
      this.branch = branch;
    }

    public void run()
    {
      try
      {
        localRepository.handleBranch(branch);
      }
      catch (Exception ex)
      {
        fireThrowable(ex);
      }
    }

    @Override
    public int compareTo(PriorityQueueRunnable o)
    {
      int result = super.compareTo(o);
      if (result == 0)
      {
        result = branch.compareTo(((BranchRunnable)o).branch);
      }

      return result;
    }

    @Override
    protected Integer getPriority()
    {
      return BRANCH_PRIORITY;
    }
  }

  /**
   * @author Eike Stepper
   */
  private abstract class RetryingRunnable extends PriorityQueueRunnable
  {
    private List<Exception> failedRuns;

    public RetryingRunnable()
    {
    }

    public void run()
    {
      try
      {
        doRun();
      }
      catch (Exception ex)
      {
        fireThrowable(ex);
        if (failedRuns == null)
        {
          failedRuns = new ArrayList<Exception>();
        }

        failedRuns.add(ex);
        if (failedRuns.size() <= maxRecommits)
        {
          if (TRACER.isEnabled())
          {
            String simpleName = RetryingRunnable.this.getClass().getSimpleName();
            TRACER.format(simpleName + " failed. Trying again in {0} seconds...", recommitInterval); //$NON-NLS-1$
          }

          if (recommitTimer == null)
          {
            recommitTimer = new Timer("RetryTimer-" + RepositorySynchronizer.this);
          }

          recommitTimer.schedule(new TimerTask()
          {
            @Override
            public void run()
            {
              try
              {
                addWork(RetryingRunnable.this);
              }
              catch (Exception ex)
              {
                if (TRACER.isEnabled())
                {
                  TRACER.format("{0} failed. Exiting.", RetryingRunnable.this.getClass().getSimpleName()); //$NON-NLS-1$
                }

                fireThrowable(ex);
              }
            }
          }, recommitInterval * 1000L);
        }
        else
        {
          if (TRACER.isEnabled())
          {
            TRACER.trace(ex);
          }

          fireThrowable(ex);
        }
      }
    }

    protected abstract void doRun();

    protected abstract String getErrorMessage();
  }

  /**
   * @author Eike Stepper
   */
  private final class CommitRunnable extends RetryingRunnable
  {
    private CDOCommitInfo commitInfo;

    public CommitRunnable(CDOCommitInfo commitInfo)
    {
      this.commitInfo = commitInfo;
    }

    @Override
    protected void doRun()
    {
      localRepository.handleCommitInfo(commitInfo);
    }

    @Override
    public int compareTo(PriorityQueueRunnable o)
    {
      int result = super.compareTo(o);
      if (result == 0)
      {
        Long timeStamp = commitInfo.getTimeStamp();
        Long timeStamp2 = ((CommitRunnable)o).commitInfo.getTimeStamp();
        result = timeStamp < timeStamp2 ? -1 : timeStamp == timeStamp2 ? 0 : 1;
      }

      return result;
    }

    @Override
    protected Integer getPriority()
    {
      return COMMIT_PRIORITY;
    }

    @Override
    protected String getErrorMessage()
    {
      return "Replication of master commit failed:" + commitInfo;
    }
  }

  /**
   * @author Caspar De Groot
   */
  private final class LocksRunnable extends RetryingRunnable
  {
    private CDOLockChangeInfo lockChangeInfo;

    public LocksRunnable(CDOLockChangeInfo lockChangeInfo)
    {
      this.lockChangeInfo = lockChangeInfo;
    }

    @Override
    protected Integer getPriority()
    {
      return LOCKS_PRIORITY;
    }

    @Override
    protected void doRun()
    {
      try
      {
        StoreThreadLocal.setSession(localRepository.getReplicatorSession());

        if (lockChangeInfo instanceof CDOBranchAdjustable)
        {
          ((CDOBranchAdjustable)lockChangeInfo).adjustBranches(localRepository.getBranchManager());
        }

        localRepository.handleLockChangeInfo(lockChangeInfo);
      }
      finally
      {
        StoreThreadLocal.release();
      }
    }

    @Override
    protected String getErrorMessage()
    {
      return "Replication of master lock changes failed:" + lockChangeInfo;
    }
  }
}
