/*
 * Copyright (c) 2004-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.explorer.checkouts;

import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.explorer.repositories.CDORepository;
import org.eclipse.emf.cdo.internal.explorer.AbstractElement;
import org.eclipse.emf.cdo.internal.explorer.AbstractManager;
import org.eclipse.emf.cdo.internal.explorer.bundle.OM;
import org.eclipse.emf.cdo.internal.explorer.repositories.CDORepositoryImpl;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.ReadOnlyException;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent;
import org.eclipse.emf.cdo.view.CDOViewTargetChangedEvent;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.ILifecycleEvent;
import org.eclipse.net4j.util.lifecycle.ILifecycleEvent.Kind;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOView;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.WeakHashMap;

/**
 * @author Eike Stepper
 */
public abstract class CDOCheckoutImpl extends AbstractElement implements CDOCheckout
{
  public static final String PROP_ROOT_ID = "rootID";

  public static final String PROP_READ_ONLY = "readOnly";

  public static final String PROP_TIME_STAMP = "timeStamp";

  public static final String PROP_BRANCH_ID = "branchID";

  public static final String PROP_BRANCH_PATH = "branchPath";

  public static final String PROP_BRANCH_POINTS = "branchPoints";

  public static final String PROP_REPOSITORY = "repository";

  public static final String EDITOR_PROPERTIES = "editor.properties";

  public static final String CHECKOUT_KEY = CDOCheckout.class.getName();

  private static final CDOBranchPoint[] NO_BRANCH_POINTS = {};

  private static final int BRANCH_POINTS_MAX = 10;

  private static final String BRANCH_POINT_SEPARATOR = ",";

  private static final String BRANCH_AND_POINT_SEPARATOR = "_";

  private final Set<CDOView> views = new HashSet<CDOView>();

  private final Map<CDOID, String> editorIDs = new WeakHashMap<CDOID, String>();

  private CDORepository repository;

  private int branchID;

  private String branchPath;

  private String branchPoints;

  private long timeStamp;

  private boolean readOnly;

  private CDOID rootID;

  private State state = State.Closed;

  private CDOView view;

  private EObject rootObject;

  private URI uri;

  public CDOCheckoutImpl()
  {
  }

  public CDOCheckoutImpl(boolean readOnly)
  {
    this.readOnly = readOnly;
  }

  @Override
  public final CDOCheckoutManagerImpl getManager()
  {
    return OM.getCheckoutManager();
  }

  public final CDORepository getRepository()
  {
    return repository;
  }

  public final int getBranchID()
  {
    return branchID;
  }

  public final void setBranchID(int branchID)
  {
    setBranchPoint(branchID, timeStamp);
  }

  public String getBranchPath()
  {
    return branchPath;
  }

  public final void setBranchPath(String branchPath)
  {
    if (!ObjectUtil.equals(this.branchPath, branchPath))
    {
      this.branchPath = branchPath;
      save();
    }
  }

  public final CDOBranchPoint getBranchPoint()
  {
    return view;
  }

  public final void setBranchPoint(CDOBranchPoint branchPoint)
  {
    int branchID = branchPoint.getBranch().getID();
    long timeStamp = branchPoint.getTimeStamp();
    setBranchPoint(branchID, timeStamp);
  }

  public final void setBranchPoint(int branchID, long timeStamp)
  {
    if (this.branchID != branchID || this.timeStamp != timeStamp)
    {
      addBranchPoint(this.branchID, this.timeStamp);

      this.branchID = branchID;
      this.timeStamp = timeStamp;

      if (isOpen())
      {
        branchPath = doSetBranchPoint(branchID, timeStamp);

        for (CDOView view : getViews())
        {
          if (view != this.view)
          {
            view.setBranchPoint(this.view);
          }
        }
      }
      else
      {
        branchPath = null;
      }

      save();
    }
  }

  public final CDOBranchPoint getBranchPoint(CDOCheckout fromCheckout)
  {
    if (repository == fromCheckout.getRepository() && repository.isConnected())
    {

      CDOBranchManager branchManager = repository.getSession().getBranchManager();
      CDOBranch branch = branchManager.getBranch(fromCheckout.getBranchID());
      return branch.getPoint(fromCheckout.getTimeStamp());
    }

    return null;
  }

  protected String doSetBranchPoint(int branchID, long timeStamp)
  {
    CDOBranch branch = view.getSession().getBranchManager().getBranch(branchID);
    view.setBranchPoint(branch.getPoint(timeStamp));
    return branch.getPathName();
  }

  public CDOBranchPoint[] getBranchPoints()
  {
    if (branchPoints != null && isOpen())
    {
      List<CDOBranchPoint> result = new ArrayList<CDOBranchPoint>();
      CDOBranchManager branchManager = view.getSession().getBranchManager();

      for (String token : branchPoints.split(BRANCH_POINT_SEPARATOR))
      {
        String[] branchAndPoint = token.split(BRANCH_AND_POINT_SEPARATOR);
        int branchID = Integer.parseInt(branchAndPoint[0]);
        CDOBranch branch = branchManager.getBranch(branchID);
        if (branch != null)
        {
          long timeStamp;
          if (branchAndPoint.length >= 2)
          {
            timeStamp = Long.parseLong(branchAndPoint[1]);
          }
          else
          {
            timeStamp = CDOBranchPoint.UNSPECIFIED_DATE;
          }

          result.add(branch.getPoint(timeStamp));
        }
      }

      return result.toArray(new CDOBranchPoint[result.size()]);
    }

    return NO_BRANCH_POINTS;
  }

  public boolean addBranchPoint(CDOBranchPoint branchPoint)
  {
    int branchID = branchPoint.getBranch().getID();
    long timeStamp = branchPoint.getTimeStamp();

    boolean changed = addBranchPoint(branchID, timeStamp);
    if (changed)
    {
      save();
    }

    return changed;
  }

  private boolean addBranchPoint(int branchID, long timeStamp)
  {
    String oldBranchPoints = branchPoints;

    String newToken = Integer.toString(branchID);
    if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
    {
      newToken += BRANCH_AND_POINT_SEPARATOR + timeStamp;
    }

    if (branchPoints != null)
    {
      StringBuilder builder = new StringBuilder(newToken);
      int count = 1;

      for (String token : branchPoints.split(BRANCH_POINT_SEPARATOR))
      {
        if (count++ == BRANCH_POINTS_MAX)
        {
          break;
        }

        if (!token.equals(newToken))
        {
          builder.append(BRANCH_POINT_SEPARATOR);
          builder.append(token);
        }
      }

      branchPoints = builder.toString();
    }
    else
    {
      branchPoints = newToken;
    }

    if (!ObjectUtil.equals(branchPoints, oldBranchPoints))
    {
      return true;
    }

    return false;
  }

  public final long getTimeStamp()
  {
    return timeStamp;
  }

  public final void setTimeStamp(long timeStamp)
  {
    setBranchPoint(branchID, timeStamp);
  }

  public final boolean isReadOnly()
  {
    return readOnly;
  }

  public void setReadOnly(boolean readOnly)
  {
    if (state != State.Closed)
    {
      throw new IllegalStateException("Checkout is not closed: " + this);
    }

    if (this.readOnly != readOnly)
    {
      this.readOnly = readOnly;
      save();
    }
  }

  public final CDOID getRootID()
  {
    return rootID;
  }

  public final void setRootID(CDOID rootID)
  {
    this.rootID = rootID;
  }

  public final State getState()
  {
    return state;
  }

  public final boolean isOpen()
  {
    return view != null;
  }

  public final void open()
  {
    CDOCheckoutManagerImpl manager = getManager();
    State oldState = null;
    State newState = null;

    try
    {
      synchronized (this)
      {
        oldState = state;

        if (!isOpen())
        {
          try
          {
            state = State.Opening;
            if (manager != null)
            {
              manager.fireCheckoutOpenEvent(this, null, oldState, state);
            }

            oldState = state;

            prepareOpen();
            CDOSession session = ((CDORepositoryImpl)repository).openCheckout(this);

            view = openView(session);
            view.addListener(new LifecycleEventAdapter()
            {
              @Override
              protected void onDeactivated(ILifecycle lifecycle)
              {
                removeView(view);
                if (state != State.Closing)
                {
                  close();
                }
              }
            });

            configureView(view);

            rootObject = loadRootObject();
            rootObject.eAdapters().add(this);

            state = State.Open;
            newState = state;
          }
          catch (RuntimeException ex)
          {
            view = null;
            rootObject = null;
            state = State.Closed;
            newState = state;
            throw ex;
          }
          catch (Error ex)
          {
            view = null;
            rootObject = null;
            state = State.Closed;
            newState = state;
            throw ex;
          }
        }
      }
    }
    finally
    {
      if (manager != null && oldState != null && newState != null && newState != oldState)
      {
        manager.fireCheckoutOpenEvent(this, view, oldState, newState);
      }
    }
  }

  protected void prepareOpen()
  {
    // Do nothing.
  }

  public final void close()
  {
    boolean closed = false;
    CDOView oldView = null;

    synchronized (this)
    {
      if (isOpen())
      {
        try
        {
          state = State.Closing;
          oldView = view;

          try
          {
            rootObject.eAdapters().remove(this);
            closeView();

            CDOView[] remainingViews = getViews();
            for (CDOView remainingView : remainingViews)
            {
              remainingView.close();
            }
          }
          finally
          {
            ((CDORepositoryImpl)repository).closeCheckout(this);
          }
        }
        finally
        {
          rootObject = null;
          view = null;
          state = State.Closed;
        }

        closed = true;
      }
    }

    if (closed)
    {
      CDOCheckoutManagerImpl manager = getManager();
      if (manager != null)
      {
        manager.fireCheckoutOpenEvent(this, oldView, State.Open, State.Closed);
      }
    }
  }

  private void addView(CDOView view)
  {
    synchronized (this)
    {
      views.add(view);
    }
  }

  private void removeView(CDOView view)
  {
    synchronized (this)
    {
      views.remove(view);
    }
  }

  public CDOView[] getViews()
  {
    synchronized (this)
    {
      return views.toArray(new CDOView[views.size()]);
    }
  }

  public final CDOView getView()
  {
    return view;
  }

  public final URI getURI()
  {
    return uri;
  }

  public final EObject getRootObject()
  {
    return rootObject;
  }

  public final ObjectType getRootType()
  {
    return ObjectType.valueFor(rootObject);
  }

  protected ResourceSetImpl createResourceSet()
  {
    return new ResourceSetImpl();
  }

  public final CDOView openView()
  {
    return openView(createResourceSet());
  }

  public CDOView openView(ResourceSet resourceSet)
  {
    return openView(readOnly, resourceSet);
  }

  public final CDOView openView(boolean readOnly)
  {
    return openView(readOnly, createResourceSet());
  }

  public CDOView openView(boolean readOnly, ResourceSet resourceSet)
  {
    return openAndConfigureView(readOnly, resourceSet);
  }

  public final CDOTransaction openTransaction()
  {
    return openTransaction(createResourceSet());
  }

  public CDOTransaction openTransaction(ResourceSet resourceSet)
  {
    if (readOnly)
    {
      throw new ReadOnlyException("Checkout '" + getLabel() + "' is read-only");
    }

    return (CDOTransaction)openAndConfigureView(false, resourceSet);
  }

  private CDOView openAndConfigureView(boolean readOnly, ResourceSet resourceSet)
  {
    CDOView view = doOpenView(readOnly, resourceSet);
    view = configureView(view);

    EObject object = view.getObject(rootObject);
    object.eAdapters().add(this);

    return view;
  }

  protected CDOView doOpenView(boolean readOnly, ResourceSet resourceSet)
  {
    if (view == null)
    {
      return null;
    }

    CDOSession session = view.getSession();
    CDOBranch branch = view.getBranch();
    CDOBranchPoint head = branch.getHead();

    if (readOnly)
    {
      return session.openView(head, resourceSet);
    }

    return session.openTransaction(head, resourceSet);
  }

  protected CDOView configureView(final CDOView view)
  {
    CDOUtil.configureView(view);
    ((InternalCDOView)view).setRepositoryName(repository.getLabel());

    view.properties().put(CHECKOUT_KEY, this);
    view.addListener(new IListener()
    {
      public void notifyEvent(IEvent event)
      {
        if (event instanceof CDOViewLocksChangedEvent)
        {
          CDOViewLocksChangedEvent e = (CDOViewLocksChangedEvent)event;
          EObject[] objects = e.getAffectedObjects();
          if (objects.length != 0)
          {
            CDOCheckoutManagerImpl manager = getManager();
            if (manager != null)
            {
              manager.fireElementsChangedEvent(objects);
            }
          }
        }
        else if (event instanceof CDOViewTargetChangedEvent)
        {
          CDOViewTargetChangedEvent e = (CDOViewTargetChangedEvent)event;
          setBranchPoint(e.getBranchPoint());
        }
        else if (event instanceof ILifecycleEvent)
        {
          ILifecycleEvent e = (ILifecycleEvent)event;
          if (e.getKind() == Kind.DEACTIVATED)
          {
            removeView(view);
          }
        }
      }
    });

    URI from = URI.createURI("cdo://" + view.getSession().getRepositoryInfo().getUUID() + "/");
    URI to = uri.appendSegment("");
    view.getResourceSet().getURIConverter().getURIMap().put(from, to);

    addView(view);
    return view;
  }

  public URI createResourceURI(String path)
  {
    if (StringUtil.isEmpty(path))
    {
      path = "";
    }
    else if (!path.startsWith("/"))
    {
      path = "/" + path;
    }

    return URI.createURI(CDOCheckoutViewProvider.SCHEME + "://" + getID() + path);
  }

  public String getEditorOpenerID(CDOID objectID)
  {
    synchronized (editorIDs)
    {
      String editorID = editorIDs.get(objectID);
      if (editorID != null)
      {
        return editorID;
      }

      Properties properties = AbstractManager.loadProperties(getFolder(), EDITOR_PROPERTIES);
      if (properties != null)
      {
        String idString = getCDOIDString(objectID);
        return properties.getProperty(idString);
      }

      return null;
    }
  }

  public void setEditorOpenerID(CDOID objectID, String editorID)
  {
    synchronized (editorIDs)
    {
      String exisingEditorID = editorIDs.get(objectID);
      if (ObjectUtil.equals(exisingEditorID, editorID))
      {
        return;
      }

      Properties properties = AbstractManager.loadProperties(getFolder(), EDITOR_PROPERTIES);
      if (properties == null)
      {
        properties = new Properties();
      }

      String idString = getCDOIDString(objectID);
      properties.setProperty(idString, editorID);

      saveProperties(EDITOR_PROPERTIES, properties);
      editorIDs.put(objectID, editorID);
    }
  }

  @Override
  public void delete(boolean deleteContents)
  {
    close();

    CDOCheckoutManagerImpl manager = getManager();
    if (manager != null)
    {
      manager.removeElement(this);
    }

    super.delete(deleteContents);

    ((CDORepositoryImpl)repository).removeCheckout(this);
    repository = null;
  }

  @Override
  public boolean isAdapterForType(Object type)
  {
    if (type == CDOCheckout.class)
    {
      return true;
    }

    return super.isAdapterForType(type);
  }

  @Override
  @SuppressWarnings({ "rawtypes" })
  public Object getAdapter(Class adapter)
  {
    if (isOpen())
    {
      if (adapter == CDOView.class)
      {
        return view;
      }
    }

    return super.getAdapter(adapter);
  }

  @Override
  public String toString()
  {
    return getLabel();
  }

  @Override
  protected void init(File folder, String type, Properties properties)
  {
    super.init(folder, type, properties);

    String repositoryID = properties.getProperty(PROP_REPOSITORY);
    repository = OM.getRepositoryManager().getElement(repositoryID);
    if (repository == null)
    {
      throw new IllegalStateException("Repository not found: " + repositoryID);
    }

    branchID = Integer.parseInt(properties.getProperty(PROP_BRANCH_ID));
    branchPath = properties.getProperty(PROP_BRANCH_PATH);
    branchPoints = properties.getProperty(PROP_BRANCH_POINTS);
    timeStamp = Long.parseLong(properties.getProperty(PROP_TIME_STAMP));
    readOnly = isOnline() ? Boolean.parseBoolean(properties.getProperty(PROP_READ_ONLY)) : false;

    String property = properties.getProperty(PROP_ROOT_ID);
    if (property != null)
    {
      rootID = CDOIDUtil.read(property);
    }

    uri = createResourceURI(null);
    ((CDORepositoryImpl)repository).addCheckout(this);
  }

  @Override
  protected void collectProperties(Properties properties)
  {
    super.collectProperties(properties);
    properties.setProperty(PROP_REPOSITORY, repository.getID());
    properties.setProperty(PROP_BRANCH_ID, Integer.toString(branchID));
    properties.setProperty(PROP_TIME_STAMP, Long.toString(timeStamp));
    properties.setProperty(PROP_READ_ONLY, Boolean.toString(isOnline() ? readOnly : false));

    if (branchPath != null)
    {
      properties.setProperty(PROP_BRANCH_PATH, branchPath);
    }

    if (branchPoints != null)
    {
      properties.setProperty(PROP_BRANCH_POINTS, branchPoints);
    }

    if (!CDOIDUtil.isNull(rootID))
    {
      String string = getCDOIDString(rootID);
      properties.setProperty(PROP_ROOT_ID, string);
    }
  }

  protected IManagedContainer getContainer()
  {
    return IPluginContainer.INSTANCE;
  }

  protected EObject loadRootObject()
  {
    if (CDOIDUtil.isNull(rootID))
    {
      rootID = view.getSession().getRepositoryInfo().getRootResourceID();
    }

    InternalCDOObject cdoObject = (InternalCDOObject)view.getObject(rootID);
    return cdoObject.cdoInternalInstance();
  }

  protected abstract CDOView openView(CDOSession session);

  protected void closeView()
  {
    view.close();
  }

  public static String getCDOIDString(CDOID id)
  {
    StringBuilder builder = new StringBuilder();
    CDOIDUtil.write(builder, id);
    return builder.toString();
  }
}
