/*******************************************************************************
 * Copyright (c) 2011 BSI Business Systems Integration AG.
 * 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:
 *     Daniel Wiehl (BSI Business Systems Integration AG) - initial API and implementation
 ******************************************************************************/
/**
 *
 */
package org.eclipse.scout.sdk.ws.jaxws.resource;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.scout.commons.CompareUtility;
import org.eclipse.scout.sdk.ws.jaxws.JaxWsSdk;

public class ManagedResource {

  /**
   * modification stamp to indicate that API changed resource to omit JDT Resource Changed notification.
   * Invoke {@link ManagedResource#setModificationStamp(long)} with this code prior to write resource to disk. It is
   * important to reset the modification stamp after having written to disk.
   */
  public static final int API_MODIFICATION_STAMP = Integer.MAX_VALUE;

  protected long m_modificationStamp;
  private IProject m_project;
  protected IFile m_file;
  protected Object m_fileLock;
  private Object m_registrationLock;

  private IResourceChangeListener m_jdtResourceChangedListener;
  private List<P_ResourceListenerEntry> m_resourceListeners;

  public ManagedResource(IProject project) {
    m_project = project;
    m_fileLock = new Object();
    m_registrationLock = new Object();
    m_resourceListeners = new ArrayList<P_ResourceListenerEntry>();
    m_jdtResourceChangedListener = new P_JdtResourceChangedListener();
  }

  private void attachJdtResourceChangeListener() {
    ResourcesPlugin.getWorkspace().addResourceChangeListener(m_jdtResourceChangedListener);
  }

  private void detachJdtResourceChangeListener() {
    ResourcesPlugin.getWorkspace().removeResourceChangeListener(m_jdtResourceChangedListener);
  }

  /**
   * To receive notifications when this resource change.
   * 
   * @param listener
   */
  public void addResourceListener(IResourceListener listener) {
    addResourceListener(null, null, listener);
  }

  /**
   * To receive notifications when this resource change.
   * 
   * @param element
   *          To only receive notification that origin of the given element within the resource.
   * @param listener
   */
  public void addResourceListener(String element, IResourceListener listener) {
    addResourceListener(element, null, listener);
  }

  /**
   * To receive notifications when this resource change.
   * 
   * @param event
   *          the event to be interested in receiving notifications. This is <em>bitwise OR</em>'ing together event
   *          constants defined in {@link IResourceListener}.
   * @param listener
   */
  public void addResourceListener(Integer event, IResourceListener listener) {
    addResourceListener(null, event, listener);
  }

  /**
   * To receive notifications when this resource change.
   * 
   * @param element
   *          To only receive notification that origin of the given element within the resource.
   * @param event
   *          To only receive notification of the given event. This is <em>bitwise OR</em>'ing together event
   *          constants defined in {@link IResourceListener}.
   * @param listener
   */
  public void addResourceListener(String element, Integer event, IResourceListener listener) {
    P_ResourceListenerEntry entry = new P_ResourceListenerEntry();
    entry.setElement(element);
    entry.setEvent(event);
    entry.setListener(listener);

    synchronized (m_registrationLock) {
      if (m_resourceListeners.size() == 0) {
        attachJdtResourceChangeListener();
      }

      m_resourceListeners.add(entry);
    }
  }

  public void removeResourceListener(IResourceListener listener) {
    synchronized (m_registrationLock) {
      for (P_ResourceListenerEntry entry : m_resourceListeners.toArray(new P_ResourceListenerEntry[m_resourceListeners.size()])) {
        if (entry.getListener() == listener) {
          m_resourceListeners.remove(entry);
        }
      }

      if (m_resourceListeners.size() == 0) {
        detachJdtResourceChangeListener();
      }
    }
  }

  public IFile getFile() {
    synchronized (m_fileLock) {
      return m_file;
    }
  }

  public boolean isSameFile(IFile file) {
    if (file == null || m_file == null) {
      return false;
    }
    return file.getProjectRelativePath().equals(m_file.getProjectRelativePath());
  }

  public void setFile(IFile file) {
    synchronized (m_fileLock) {
      m_modificationStamp = IResource.NULL_STAMP;
      m_file = file;
    }
  }

  public boolean existsFile() {
    return m_file != null && m_file.exists();
  }

  protected long getModificationStamp() {
    return m_modificationStamp;
  }

  protected void setModificationStamp(long modificationStamp) {
    m_modificationStamp = modificationStamp;
  }

  public void touch() {
    m_modificationStamp = IResource.NULL_STAMP;
  }

  /**
   * To notify listeners about a change.
   * 
   * @param element
   *          the element that changed (defined in {@link IResourceListener})
   * @param event
   *          the events that describes the change. This is <em>bitwise OR</em>'ing together events described in
   *          {@link IResourceListener}
   */
  protected void notifyResourceListeners(String element, Integer event) {
    if (element == null) {
      throw new IllegalArgumentException("element must not be null");
    }
    if (event == null) {
      throw new IllegalArgumentException("event must not be null");
    }

    Set<IResourceListener> listenersProcessed = new HashSet<IResourceListener>();

    for (P_ResourceListenerEntry entry : m_resourceListeners.toArray(new P_ResourceListenerEntry[m_resourceListeners.size()])) {
      if (!listenersProcessed.contains(entry.getListener()) &&
          (entry.getElement() == null || entry.getElement().equals(element)) &&
          (entry.getEvent() == null || (entry.getEvent() & event) > 0)) {
        try {
          entry.getListener().changed(element, event);
        }
        catch (Throwable e) {
          // failsafe
          JaxWsSdk.logError("Error occured while notifying listener about change", e);
        }
        finally {
          listenersProcessed.add(entry.getListener());
        }
      }
    }
  }

  private class P_JdtResourceChangedListener implements IResourceChangeListener {

    @Override
    public void resourceChanged(IResourceChangeEvent event) {
      if (m_file == null) {
        return;
      }

      // there is only interest in POST_CHANGE events
      if (event.getType() != IResourceChangeEvent.POST_CHANGE) {
        return;
      }

      try {
        IResourceDelta rootDelta = event.getDelta();
        rootDelta.accept(new IResourceDeltaVisitor() {

          @Override
          public boolean visit(IResourceDelta delta) throws CoreException {
            if (delta.getKind() == IResourceDelta.REMOVED || delta.getKind() == IResourceDelta.REPLACED || delta.getKind() == IResourceDelta.ADDED || (delta.getKind() == IResourceDelta.CHANGED && (delta.getFlags() & IResourceDelta.CONTENT) != 0)) { // it is crucial to exclude marker update events
              IResource candidate = delta.getResource();

              if (candidate.getType() != IResource.FILE) {
                return true;
              }

              if (candidate.getProject() != m_project) {
                return false;
              }

              if (CompareUtility.equals(candidate, m_file)) {
                // only notify if modification stamp of resource is different to current stamp.
                // This is to exclude workspace modifications caused by API code
                if (m_modificationStamp != API_MODIFICATION_STAMP && (m_modificationStamp == IResource.NULL_STAMP || m_modificationStamp != m_file.getModificationStamp())) {
                  notifyResourceListeners(IResourceListener.ELEMENT_FILE, IResourceListener.EVENT_UNKNOWN);
                }
                return false;
              }
            }
            return true;
          }
        });
      }
      catch (Exception e) {
        JaxWsSdk.logError("Unexpected error occured while intercepting 'Resource Change' event.", e);
      }
    }
  }

  private class P_ResourceListenerEntry {
    private IResourceListener m_listener;

    /**
     * the source the listener is interested in to receive notifications
     */
    private String m_element;
    /**
     * the event the listener is interested in to receive notifications
     */
    private Integer m_event;

    public IResourceListener getListener() {
      return m_listener;
    }

    public void setListener(IResourceListener listener) {
      m_listener = listener;
    }

    public String getElement() {
      return m_element;
    }

    public void setElement(String element) {
      m_element = element;
    }

    public Integer getEvent() {
      return m_event;
    }

    public void setEvent(Integer event) {
      m_event = event;
    }
  }
}
