/*
 * Copyright (c) 2007-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
 *    Simon McDuff - bug 201266
 *    Simon McDuff - bug 230832
 *    Simon McDuff - bug 233490
 *    Simon McDuff - bug 213402
 */
package org.eclipse.emf.cdo.internal.server;

import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.CDOCommonSession;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchChangedEvent.ChangeKind;
import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.CDORevisionProvider;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.security.CDOPermission;
import org.eclipse.emf.cdo.internal.common.commit.DelegatingCommitInfo;
import org.eclipse.emf.cdo.server.IPermissionManager;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.spi.server.ISessionProtocol;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalSession;
import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
import org.eclipse.emf.cdo.spi.server.InternalTransaction;
import org.eclipse.emf.cdo.spi.server.InternalView;

import org.eclipse.net4j.util.AdapterUtil;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.collection.IndexedList;
import org.eclipse.net4j.util.container.Container;
import org.eclipse.net4j.util.event.EventUtil;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.log.OMLogger;
import org.eclipse.net4j.util.registry.HashMapRegistry;
import org.eclipse.net4j.util.registry.IRegistry;

import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Eike Stepper
 */
public class Session extends Container<IView>implements InternalSession
{
  private InternalSessionManager manager;

  private ISessionProtocol protocol;

  private int sessionID;

  private String userID;

  private boolean passiveUpdateEnabled = true;

  private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;

  private LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS;

  private long lastUpdateTime;

  @ExcludeFromDump
  private Object lastUpdateTimeLock = new Object();

  private ConcurrentMap<Integer, InternalView> views = new ConcurrentHashMap<Integer, InternalView>();

  private AtomicInteger lastTempViewID = new AtomicInteger();

  private final IRegistry<String, Object> properties = new HashMapRegistry<String, Object>()
  {
    @Override
    public void setAutoCommit(boolean autoCommit)
    {
      throw new UnsupportedOperationException();
    }
  };

  @ExcludeFromDump
  private IListener protocolListener = new LifecycleEventAdapter()
  {
    @Override
    protected void onDeactivated(ILifecycle lifecycle)
    {
      deactivate();
    }
  };

  private boolean subscribed;

  /**
   * @since 2.0
   */
  public Session(InternalSessionManager manager, ISessionProtocol protocol, int sessionID, String userID)
  {
    this.manager = manager;
    this.protocol = protocol;
    this.sessionID = sessionID;
    this.userID = userID;

    EventUtil.addListener(protocol, protocolListener);
    activate();
  }

  /**
   * @since 2.0
   */
  public Options options()
  {
    return this;
  }

  public final IRegistry<String, Object> properties()
  {
    return properties;
  }

  /**
   * @since 2.0
   */
  public CDOCommonSession getContainer()
  {
    return this;
  }

  public InternalSessionManager getManager()
  {
    return manager;
  }

  public CDOBranchManager getBranchManager()
  {
    return manager.getRepository().getBranchManager();
  }

  public ISessionProtocol getProtocol()
  {
    return protocol;
  }

  public int getSessionID()
  {
    return sessionID;
  }

  /**
   * @since 2.0
   */
  public String getUserID()
  {
    return userID;
  }

  public void setUserID(String userID)
  {
    this.userID = userID;
  }

  /**
   * @since 2.0
   */
  public boolean isSubscribed()
  {
    return subscribed;
  }

  /**
   * @since 2.0
   */
  public void setSubscribed(boolean subscribed)
  {
    checkActive();
    if (this.subscribed != subscribed)
    {
      this.subscribed = subscribed;
      byte opcode = subscribed ? CDOProtocolConstants.REMOTE_SESSION_SUBSCRIBED
          : CDOProtocolConstants.REMOTE_SESSION_UNSUBSCRIBED;
      manager.sendRemoteSessionNotification(this, opcode);
    }
  }

  /**
   * @since 2.0
   */
  public boolean isPassiveUpdateEnabled()
  {
    return passiveUpdateEnabled;
  }

  /**
   * @since 2.0
   */
  public void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
  {
    checkActive();
    this.passiveUpdateEnabled = passiveUpdateEnabled;
  }

  public PassiveUpdateMode getPassiveUpdateMode()
  {
    return passiveUpdateMode;
  }

  public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode)
  {
    checkActive();
    checkArg(passiveUpdateMode, "passiveUpdateMode");
    this.passiveUpdateMode = passiveUpdateMode;
  }

  public LockNotificationMode getLockNotificationMode()
  {
    return lockNotificationMode;
  }

  public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
  {
    checkActive();
    checkArg(lockNotificationMode, "lockNotificationMode");
    this.lockNotificationMode = lockNotificationMode;
  }

  @Deprecated
  public long getLastUpdateTime()
  {
    synchronized (lastUpdateTimeLock)
    {
      return lastUpdateTime;
    }
  }

  public InternalView[] getElements()
  {
    checkActive();
    return getViews();
  }

  @Override
  public boolean isEmpty()
  {
    checkActive();
    return views.isEmpty();
  }

  public InternalView[] getViews()
  {
    checkActive();
    return getViewsArray();
  }

  private InternalView[] getViewsArray()
  {
    return views.values().toArray(new InternalView[views.size()]);
  }

  public InternalView getView(int viewID)
  {
    checkActive();
    return views.get(viewID);
  }

  /**
   * @since 2.0
   */
  public InternalView openView(int viewID, CDOBranchPoint branchPoint)
  {
    checkActive();
    if (viewID == TEMP_VIEW_ID)
    {
      viewID = -lastTempViewID.incrementAndGet();
    }

    InternalView view = new View(this, viewID, branchPoint);
    view.activate();
    addView(view);
    return view;
  }

  /**
   * @since 2.0
   */
  public InternalTransaction openTransaction(int viewID, CDOBranchPoint branchPoint)
  {
    checkActive();
    if (viewID == TEMP_VIEW_ID)
    {
      viewID = -lastTempViewID.incrementAndGet();
    }

    InternalTransaction transaction = new Transaction(this, viewID, branchPoint);
    transaction.activate();
    addView(transaction);
    return transaction;
  }

  private void addView(InternalView view)
  {
    checkActive();
    int viewID = view.getViewID();
    views.put(viewID, view);
    fireElementAddedEvent(view);
  }

  /**
   * @since 2.0
   */
  public void viewClosed(InternalView view)
  {
    int viewID = view.getViewID();
    if (views.remove(viewID) == view)
    {
      view.doClose();
      fireElementRemovedEvent(view);
    }
  }

  /**
   * TODO I can't see how recursion is controlled/limited
   *
   * @since 2.0
   */
  public void collectContainedRevisions(InternalCDORevision revision, CDOBranchPoint branchPoint, int referenceChunk,
      Set<CDOID> revisions, List<CDORevision> additionalRevisions)
  {
    InternalCDORevisionManager revisionManager = getManager().getRepository().getRevisionManager();
    for (EStructuralFeature feature : revision.getClassInfo().getAllPersistentFeatures())
    {
      // TODO Clarify feature maps
      if (feature instanceof EReference && !feature.isMany() && ((EReference)feature).isContainment())
      {
        Object value = revision.getValue(feature);
        if (value instanceof CDOID)
        {
          CDOID id = (CDOID)value;
          if (!CDOIDUtil.isNull(id) && !revisions.contains(id))
          {
            InternalCDORevision containedRevision = revisionManager.getRevision(id, branchPoint, referenceChunk,
                CDORevision.DEPTH_NONE, true);
            revisions.add(id);
            additionalRevisions.add(containedRevision);

            // Recurse
            collectContainedRevisions(containedRevision, branchPoint, referenceChunk, revisions, additionalRevisions);
          }
        }
      }
    }
  }

  public CDOID provideCDOID(Object idObject)
  {
    return (CDOID)idObject;
  }

  public CDOPermission getPermission(CDORevision revision, CDOBranchPoint securityContext)
  {
    IPermissionManager permissionManager = manager.getPermissionManager();
    if (permissionManager != null)
    {
      return permissionManager.getPermission(revision, securityContext, this);
    }

    return CDORevision.PERMISSION_PROVIDER.getPermission(revision, securityContext);
  }

  public void sendRepositoryTypeNotification(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType)
      throws Exception
  {
    if (protocol != null)
    {
      protocol.sendRepositoryTypeNotification(oldType, newType);
    }
  }

  @Deprecated
  public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
      throws Exception
  {
    sendRepositoryStateNotification(oldState, newState, null);
  }

  public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState,
      CDOID rootResourceID) throws Exception
  {
    if (protocol != null)
    {
      protocol.sendRepositoryStateNotification(oldState, newState, rootResourceID);
    }
  }

  @Deprecated
  public void sendBranchNotification(InternalCDOBranch branch) throws Exception
  {
    sendBranchNotification(branch, ChangeKind.CREATED);
  }

  public void sendBranchNotification(InternalCDOBranch branch, ChangeKind changeKind) throws Exception
  {
    if (protocol != null)
    {
      protocol.sendBranchNotification(branch, changeKind);
    }
  }

  @Deprecated
  public void sendCommitNotification(CDOCommitInfo commitInfo) throws Exception
  {
    throw new UnsupportedOperationException();
  }

  @Deprecated
  public void sendCommitNotification(CDOCommitInfo commitInfo, boolean clearResourcePathCache) throws Exception
  {
    throw new UnsupportedOperationException();
  }

  public void sendCommitNotification(CommitNotificationInfo notificationInfo) throws Exception
  {
    if (protocol == null)
    {
      return;
    }

    if (!isPassiveUpdateEnabled())
    {
      return;
    }

    byte securityImpact = notificationInfo.getSecurityImpact();
    if (securityImpact == CommitNotificationInfo.IMPACT_PERMISSIONS)
    {
      IPermissionManager permissionManager = manager.getPermissionManager();
      Set<? extends Object> impactedRules = notificationInfo.getImpactedRules();

      if (!permissionManager.hasAnyRule(this, impactedRules))
      {
        securityImpact = CommitNotificationInfo.IMPACT_NONE;
      }
    }

    CommitInfo sessionCommitInfo = new CommitInfo(notificationInfo);

    CommitNotificationInfo sessionNotificationInfo = new CommitNotificationInfo();
    sessionNotificationInfo.setSender(notificationInfo.getSender());
    sessionNotificationInfo.setCommitInfo(sessionCommitInfo);
    sessionNotificationInfo.setRevisionProvider(notificationInfo.getRevisionProvider());
    sessionNotificationInfo.setClearResourcePathCache(notificationInfo.isClearResourcePathCache());
    sessionNotificationInfo.setNewPermissions(sessionCommitInfo.getNewPermissions());
    sessionNotificationInfo.setSecurityImpact(securityImpact);

    protocol.sendCommitNotification(sessionNotificationInfo);

    synchronized (lastUpdateTimeLock)
    {
      CDOCommitInfo originalCommitInfo = notificationInfo.getCommitInfo();
      lastUpdateTime = originalCommitInfo.getTimeStamp();
    }
  }

  public void sendLockNotification(CDOLockChangeInfo lockChangeInfo) throws Exception
  {
    if (protocol != null)
    {
      if (options().getLockNotificationMode() == LockNotificationMode.ALWAYS)
      {
        protocol.sendLockNotification(lockChangeInfo);
        return;
      }

      if (options().getLockNotificationMode() == LockNotificationMode.IF_REQUIRED_BY_VIEWS)
      {
        // If this session has one (or more) views configured for this branch,
        // only then do we send the lockChangeInfo.
        for (InternalView view : getViews())
        {
          if (view.options().isLockNotificationEnabled())
          {
            CDOBranch affectedBranch = lockChangeInfo.getBranch();
            if (view.getBranch() == affectedBranch || affectedBranch == null)
            {
              protocol.sendLockNotification(lockChangeInfo);
              break;
            }
          }
        }
      }
    }
  }

  private boolean hasSubscription(CDOID id, InternalView[] views)
  {
    for (InternalView view : views)
    {
      if (view.hasSubscription(id))
      {
        return true;
      }
    }

    return false;
  }

  public void sendRemoteSessionNotification(InternalSession sender, byte opcode) throws Exception
  {
    if (protocol != null)
    {
      protocol.sendRemoteSessionNotification(sender, opcode);
    }
  }

  public void sendRemoteMessageNotification(InternalSession sender, CDORemoteSessionMessage message) throws Exception
  {
    if (protocol != null)
    {
      protocol.sendRemoteMessageNotification(sender, message);
    }
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Object getAdapter(Class adapter)
  {
    return AdapterUtil.adapt(this, adapter, false);
  }

  @Override
  public String toString()
  {
    String name = "unknown";
    if (manager != null)
    {
      InternalRepository repository = manager.getRepository();
      if (repository != null)
      {
        name = repository.getName();
      }
    }

    if (userID != null && userID.length() != 0)
    {
      name = userID + "@" + name;
    }

    return MessageFormat.format("Session{0} [{1}]", sessionID, name); //$NON-NLS-1$
  }

  /**
   * @since 2.0
   */
  public void close()
  {
    LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
  }

  /**
   * @since 2.0
   */
  public boolean isClosed()
  {
    return !isActive();
  }

  @Override
  protected void doDeactivate() throws Exception
  {
    EventUtil.removeListener(protocol, protocolListener);
    protocolListener = null;

    LifecycleUtil.deactivate(protocol, OMLogger.Level.DEBUG);
    protocol = null;

    for (IView view : getViewsArray())
    {
      view.close();
    }

    views = null;
    manager.sessionClosed(this);
    manager = null;
    super.doDeactivate();
  }

  /**
   * @author Eike Stepper
   */
  private final class CommitInfo extends DelegatingCommitInfo
  {
    private final CDOCommitInfo delegate;

    private final CDORevisionProvider revisionProvider;

    private final InternalView[] views;

    private final IPermissionManager permissionManager;

    private final Map<CDOID, CDOPermission> newPermissions;

    private final boolean additions;

    private final boolean changes;

    public CommitInfo(CommitNotificationInfo notificationInfo)
    {
      delegate = notificationInfo.getCommitInfo();
      revisionProvider = notificationInfo.getRevisionProvider();

      views = getViews();
      permissionManager = manager.getPermissionManager();
      if (permissionManager != null)
      {
        newPermissions = CDOIDUtil.createMap();
      }
      else
      {
        newPermissions = null;
      }

      PassiveUpdateMode passiveUpdateMode = getPassiveUpdateMode();
      additions = passiveUpdateMode == PassiveUpdateMode.ADDITIONS;
      changes = additions || passiveUpdateMode == PassiveUpdateMode.CHANGES;
    }

    @Override
    protected CDOCommitInfo getDelegate()
    {
      return delegate;
    }

    protected void addNewPermission(CDOID id, CDOPermission permission)
    {
      newPermissions.put(id, permission);
    }

    public Map<CDOID, CDOPermission> getNewPermissions()
    {
      return newPermissions;
    }

    @Override
    public List<CDOIDAndVersion> getNewObjects()
    {
      final List<CDOIDAndVersion> newObjects = super.getNewObjects();
      return new IndexedList<CDOIDAndVersion>()
      {
        @Override
        public CDOIDAndVersion get(int index)
        {
          CDORevision revision = (CDORevision)newObjects.get(index);
          if (additions)
          {
            if (permissionManager == null)
            {
              // Return full revision
              return revision;
            }

            CDOPermission permission = permissionManager.getPermission(revision, delegate, Session.this);
            CDOID id = revision.getID();
            addNewPermission(id, permission);

            if (permission != CDOPermission.NONE)
            {
              // Return full revision
              return revision;
            }
          }

          // Prevent sending full revision by copying the id and version
          return CDOIDUtil.createIDAndVersion(revision);
        }

        @Override
        public int size()
        {
          return newObjects.size();
        }
      };
    }

    @Override
    public List<CDORevisionKey> getChangedObjects()
    {
      final List<CDORevisionKey> changedObjects = super.getChangedObjects();
      return new IndexedList<CDORevisionKey>()
      {
        @Override
        public CDORevisionKey get(int index)
        {
          CDORevisionDelta revisionDelta = (CDORevisionDelta)changedObjects.get(index);
          CDOID id = revisionDelta.getID();

          if (changes || hasSubscription(id, views))
          {
            if (permissionManager == null)
            {
              // Return full delta
              return revisionDelta;
            }

            if (revisionProvider == null)
            {
              // Return full delta
              return revisionDelta;
            }

            CDORevision newRevision = revisionProvider.getRevision(id);
            CDOPermission permission = permissionManager.getPermission(newRevision, delegate, Session.this);
            addNewPermission(id, permission);

            if (permission != CDOPermission.NONE)
            {
              // Return full delta
              return revisionDelta;
            }
          }

          // Prevent sending full delta by copying the id and version
          return CDORevisionUtil.copyRevisionKey(revisionDelta);
        }

        @Override
        public int size()
        {
          return changedObjects.size();
        }
      };
    }
  }
}
