/**
 * Copyright (c) 2005-2008 IBM Corporation 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:
 * IBM - Initial API and implementation
 */

package org.eclipse.egf.core.pde.internal.ui;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.pde.core.IBaseModel;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.ISharedExtensionsModel;
import org.eclipse.pde.internal.core.bundle.BundleFragmentModel;
import org.eclipse.pde.internal.core.bundle.BundlePluginModel;
import org.eclipse.pde.internal.core.ibundle.IBundleModel;
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
import org.eclipse.pde.internal.core.text.AbstractEditingModel;
import org.eclipse.pde.internal.core.text.IEditingModel;
import org.eclipse.pde.internal.core.text.IModelTextChangeListener;
import org.eclipse.pde.internal.core.text.build.BuildModel;
import org.eclipse.pde.internal.core.text.build.PropertiesTextChangeListener;
import org.eclipse.pde.internal.core.text.bundle.BundleModel;
import org.eclipse.pde.internal.core.text.bundle.BundleTextChangeListener;
import org.eclipse.pde.internal.core.text.plugin.FragmentModel;
import org.eclipse.pde.internal.core.text.plugin.PluginModel;
import org.eclipse.pde.internal.ui.IPDEUIConstants;
import org.eclipse.pde.internal.ui.PDEPlugin;
import org.eclipse.pde.internal.ui.editor.PDEFormEditor;
import org.eclipse.pde.internal.ui.editor.build.BuildEditor;
import org.eclipse.pde.internal.ui.editor.build.BuildInputContext;
import org.eclipse.pde.internal.ui.editor.build.BuildSourcePage;
import org.eclipse.pde.internal.ui.editor.context.InputContext;
import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor;
import org.eclipse.pde.internal.ui.editor.schema.SchemaEditor;
import org.eclipse.pde.internal.ui.editor.schema.SchemaInputContext;
import org.eclipse.pde.internal.ui.editor.site.SiteEditor;
import org.eclipse.swt.widgets.Display;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.forms.editor.IFormPage;
import org.osgi.framework.Constants;

/**
 * Your one stop shop for performing changes to your plug-in models.
 */
public class PDEModelUtility {

  public static final String F_MANIFEST = "MANIFEST.MF"; //$NON-NLS-1$

  public static final String F_MANIFEST_FP = "META-INF/" + F_MANIFEST; //$NON-NLS-1$

  public static final String F_PLUGIN = "plugin.xml"; //$NON-NLS-1$

  public static final String F_FRAGMENT = "fragment.xml"; //$NON-NLS-1$

  public static final String F_PROPERTIES = ".properties"; //$NON-NLS-1$

  public static final String F_BUILD = "build" + F_PROPERTIES; //$NON-NLS-1$

  // bundle / xml various Object[] indices
  private static final int F_Bi = 0; // the manifest.mf-related object will
                                     // always be 1st

  private static final int F_Xi = 1; // the xml-related object will always be
                                     // 2nd

  @SuppressWarnings("unchecked")
  private static Hashtable fOpenPDEEditors = new Hashtable();

  /**
   * PDE editors should call this during their creation. Currently the pde
   * editor superclass (PDEFormEditor) connects during its createPages method
   * and so this
   * method does not need to be invoked anywhere else.
   * 
   * @param editor
   *          the editor to connect to
   */
  @SuppressWarnings("unchecked")
  public static void connect(PDEFormEditor editor) {
    IProject project = editor.getCommonProject();
    if (project == null) {
      return;
    }
    if (fOpenPDEEditors.containsKey(project)) {
      ArrayList list = (ArrayList) fOpenPDEEditors.get(project);
      if (list.contains(editor) == false) {
        list.add(editor);
      }
    } else {
      ArrayList list = new ArrayList();
      list.add(editor);
      fOpenPDEEditors.put(project, list);
    }
  }

  /**
   * PDE editors should call this when they are closing down.
   * 
   * @param editor
   *          the pde editor to disconnect from
   */
  @SuppressWarnings("unchecked")
  public static void disconnect(PDEFormEditor editor) {
    IProject project = editor.getCommonProject();
    if (project == null) {
      return;
    }
    if (fOpenPDEEditors.containsKey(project) == false) {
      return;
    }
    ArrayList list = (ArrayList) fOpenPDEEditors.get(project);
    list.remove(editor);
    if (list.size() == 0) {
      fOpenPDEEditors.remove(project);
    }
  }

  /**
   * Returns an open ManifestEditor that is associated with this project.
   * 
   * @param project
   * @return null if no ManifestEditor is open for this project
   */
  public static ManifestEditor getOpenManifestEditor(IProject project) {
    return (ManifestEditor) getOpenEditor(project, IPDEUIConstants.MANIFEST_EDITOR_ID);
  }

  /**
   * Returns an open BuildEditor that is associated with this project.
   * 
   * @param project
   * @return null if no BuildEditor is open for this project
   */
  public static BuildEditor getOpenBuildPropertiesEditor(IProject project) {
    return (BuildEditor) getOpenEditor(project, IPDEUIConstants.BUILD_EDITOR_ID);
  }

  /**
   * Returns an open SiteEditor that is associated with this project.
   * 
   * @param project
   * @return null if no SiteEditor is open for this project
   */
  public static SiteEditor getOpenUpdateSiteEditor(IProject project) {
    return (SiteEditor) getOpenEditor(project, IPDEUIConstants.SITE_EDITOR_ID);
  }

  @SuppressWarnings("unchecked")
  private static PDEFormEditor getOpenEditor(IProject project, String editorId) {
    ArrayList list = (ArrayList) fOpenPDEEditors.get(project);
    if (list == null) {
      return null;
    }
    for (int i = 0; i < list.size(); i++) {
      PDEFormEditor editor = (PDEFormEditor) list.get(i);
      if (editor.getEditorSite().getId().equals(editorId))
        return editor;
    }
    return null;
  }

  /**
   * Get the open schema editor rooted at the specified underlying file
   * 
   * @param file
   * @return editor if found or null
   */
  public static SchemaEditor getOpenSchemaEditor(IFile file) {
    return (SchemaEditor) getOpenEditor(IPDEUIConstants.SCHEMA_EDITOR_ID, SchemaInputContext.CONTEXT_ID, file);
  }

  /**
   * @param editorID
   * @param inputContextID
   * @param file
   * @return
   */
  @SuppressWarnings("unchecked")
  private static PDEFormEditor getOpenEditor(String editorID, String inputContextID, IFile file) {
    // Get the file's project
    IProject project = file.getProject();
    // Check for open editors housed in the specified project
    ArrayList list = (ArrayList) fOpenPDEEditors.get(project);
    // No open editors found
    if (list == null) {
      return null;
    }
    // Get the open editor whose
    // (1) Editor ID matches the specified editor ID
    // (2) Underlying file matches the specified file
    // Check all open editors
    for (int i = 0; i < list.size(); i++) {
      // Get the editor
      PDEFormEditor editor = (PDEFormEditor) list.get(i);
      // Check for the specified type
      // Get the editor ID
      String currentEditorID = editor.getEditorSite().getId();
      if (currentEditorID.equals(editorID) == false) {
        continue;
      }
      // Check for the specified file
      // Find the editor's input context
      InputContext context = editor.getContextManager().findContext(inputContextID);
      // Ensure we have an input context
      if (context == null) {
        continue;
      }
      // Get the editor input
      IEditorInput input = context.getInput();
      // Ensure we have a file editor input
      if ((input instanceof IFileEditorInput) == false) {
        continue;
      }
      // Get the editor's underlying file
      IFile currentFile = ((IFileEditorInput) input).getFile();
      // If the file matches the specified file, we have found the
      // specified editor
      if (currentFile.equals(file)) {
        return editor;
      }
    }
    return null;
  }

  /**
   * Returns an IPluginModelBase from the active ManifestEditor or null if no
   * manifest editor is open.
   * 
   * @return the active IPluginModelBase
   */
  public static IPluginModelBase getActivePluginModel() {
    IEditorPart editor = PDEPlugin.getActivePage().getActiveEditor();
    if (editor instanceof ManifestEditor) {
      IBaseModel model = ((ManifestEditor) editor).getAggregateModel();
      if (model instanceof IPluginModelBase)
        return (IPluginModelBase) model;
    }
    return null;
  }

  /**
   * @param doc
   * @return
   */
  @SuppressWarnings("unchecked")
  public static IEditingModel getOpenModel(IDocument doc) {
    Iterator it = fOpenPDEEditors.values().iterator();
    while (it.hasNext()) {
      ArrayList list = (ArrayList) it.next();
      for (int i = 0; i < list.size(); i++) {
        PDEFormEditor e = (PDEFormEditor) list.get(i);
        IPluginModelBase model = (IPluginModelBase) e.getAggregateModel();
        if (model instanceof IBundlePluginModelBase) {
          IBundleModel bModel = ((IBundlePluginModelBase) model).getBundleModel();
          if (bModel instanceof IEditingModel && doc == ((IEditingModel) bModel).getDocument()) {
            return (IEditingModel) bModel;
          }
          ISharedExtensionsModel eModel = ((IBundlePluginModelBase) model).getExtensionsModel();
          if (eModel instanceof IEditingModel && doc == ((IEditingModel) eModel).getDocument()) {
            return (IEditingModel) eModel;
          }
        }
        // IBuildModel bModel = model.getBuildModel();
        // if (bModel instanceof IEditingModel &&
        // doc == ((IEditingModel)bModel).getDocument())
        // return (IEditingModel)bModel;
        if (model instanceof IEditingModel && doc == ((IEditingModel) model).getDocument()) {
          return (IEditingModel) model;
        }
      }
    }
    return null;
  }

  /**
   * Modify a model based on the specifications provided by the
   * ModelModification parameter. A model will be searched for in the open
   * editors, if it is found
   * changes will be applied and the editor will be saved. If no model is found
   * one will be created and text edit operations will be generated / applied.
   * NOTE:
   * If a MANIFEST.MF file is specified in the ModelModification a
   * BundlePluginModel will be searched for / created and passed to
   * ModelModification#modifyModel(IBaseModel). (not a BundleModel - which can
   * be retreived from the BundlePluginModel)
   * 
   * @param modification
   * @param monitor
   * @throws CoreException
   */
  @SuppressWarnings("deprecation")
  public static void modifyModel(final ModelModification modification, final IProgressMonitor monitor) {
    // ModelModification was not supplied with the right files
    // TODO should we just fail silently?
    if (modification.getFile() == null) {
      return;
    }
    PDEFormEditor editor = getOpenEditor(modification);
    IBaseModel model = getModelFromEditor(editor, modification);
    if (model != null) {
      // open editor found, should have underlying text listeners -> apply
      // modification
      modifyEditorModel(modification, editor, model, monitor);
    } else {
      // create own model, attach listeners and grab text edits
      ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
      IFile[] files;
      if (modification.isFullBundleModification()) {
        files = new IFile[2];
        files[F_Bi] = modification.getManifestFile();
        files[F_Xi] = modification.getXMLFile();
      } else {
        files = new IFile[] { modification.getFile() };
      }
      // need to monitor number of successfull buffer connections for
      // disconnection purposes
      // @see } finally { statement
      int sc = 0;
      try {
        ITextFileBuffer[] buffers = new ITextFileBuffer[files.length];
        IDocument[] documents = new IDocument[files.length];
        for (int i = 0; i < files.length; i++) {
          if (files[i] == null || files[i].exists() == false) {
            continue;
          }
          manager.connect(files[i].getFullPath(), monitor);
          sc++;
          buffers[i] = manager.getTextFileBuffer(files[i].getFullPath());
          if (buffers[i].isDirty()) {
            buffers[i].commit(monitor, true);
          }
          documents[i] = buffers[i].getDocument();
        }

        IBaseModel editModel;
        if (modification.isFullBundleModification()) {
          editModel = prepareBundlePluginModel(files, documents);
        } else {
          editModel = prepareAbstractEditingModel(files[0], documents[0]);
        }

        modification.modifyModel(editModel, monitor);

        IModelTextChangeListener[] listeners = gatherListeners(editModel);
        for (int i = 0; i < listeners.length; i++) {
          if (listeners[i] == null) {
            continue;
          }
          TextEdit[] edits = listeners[i].getTextOperations();
          if (edits.length > 0) {
            MultiTextEdit multi = new MultiTextEdit();
            multi.addChildren(edits);
            multi.apply(documents[i]);
            buffers[i].commit(monitor, true);
          }
        }
      } catch (CoreException e) {
        PDEPlugin.log(e);
      } catch (MalformedTreeException e) {
        PDEPlugin.log(e);
      } catch (BadLocationException e) {
        PDEPlugin.log(e);
      } finally {
        // don't want to over-disconnect in case we ran into an exception during
        // connections
        // dc <= sc stops this from happening
        int dc = 0;
        for (int i = 0; i < files.length && dc <= sc; i++) {
          if (files[i] == null || files[i].exists() == false) {
            continue;
          }
          try {
            manager.disconnect(files[i].getFullPath(), monitor);
            dc++;
          } catch (CoreException e) {
            PDEPlugin.log(e);
          }
        }
      }
    }
  }

  private static void modifyEditorModel(final ModelModification mod, final PDEFormEditor editor, final IBaseModel model, final IProgressMonitor monitor) {
    getDisplay().syncExec(new Runnable() {
      public void run() {
        try {
          mod.modifyModel(model, monitor);
          IFile[] files = new IFile[] { mod.getManifestFile(), mod.getXMLFile(), mod.getPropertiesFile() };
          for (int i = 0; i < files.length; i++) {
            if (files[i] == null) {
              continue;
            }
            InputContext con = editor.getContextManager().findContext(files[i]);
            if (con != null) {
              con.flushEditorInput();
            }
          }
          if (mod.saveOpenEditor()) {
            editor.doSave(monitor);
          }
        } catch (CoreException e) {
          PDEPlugin.log(e);
        }
      }
    });
  }

  private static PDEFormEditor getOpenEditor(ModelModification modification) {
    IProject project = modification.getFile().getProject();
    String name = modification.getFile().getName();
    if (name.equals(F_PLUGIN) || name.equals(F_FRAGMENT) || name.equals(F_MANIFEST)) {
      return getOpenManifestEditor(project);
    } else if (name.equals(F_BUILD)) {
      PDEFormEditor openEditor = getOpenBuildPropertiesEditor(project);
      if (openEditor == null) {
        openEditor = getOpenManifestEditor(project);
      }
      return openEditor;
    }
    return null;
  }

  private static IBaseModel getModelFromEditor(PDEFormEditor openEditor, ModelModification modification) {
    if (openEditor == null) {
      return null;
    }
    String name = modification.getFile().getName();
    IBaseModel model = null;
    if (name.equals(F_PLUGIN) || name.equals(F_FRAGMENT)) {
      model = openEditor.getAggregateModel();
      if (model instanceof IBundlePluginModelBase) {
        model = ((IBundlePluginModelBase) model).getExtensionsModel();
      }
    } else if (name.equals(F_BUILD)) {
      if (openEditor instanceof BuildEditor) {
        model = openEditor.getAggregateModel();
      } else if (openEditor instanceof ManifestEditor) {
        IFormPage page = openEditor.findPage(BuildInputContext.CONTEXT_ID);
        if (page instanceof BuildSourcePage) {
          model = ((BuildSourcePage) page).getInputContext().getModel();
        }
      }
    } else if (name.equals(F_MANIFEST)) {
      model = openEditor.getAggregateModel();
      if (model instanceof IBundlePluginModelBase) {
        return model;
      }
    }
    if (model instanceof AbstractEditingModel) {
      return model;
    }
    return null;
  }

  private static IModelTextChangeListener createListener(String filename, IDocument doc) {
    if (filename.equals(F_PLUGIN) || filename.equals(F_FRAGMENT)) {
      return new XMLTextChangeListener(doc);
    } else if (filename.equals(F_MANIFEST)) {
      return new BundleTextChangeListener(doc);
    } else if (filename.endsWith(F_PROPERTIES)) {
      return new PropertiesTextChangeListener(doc);
    }
    return null;
  }

  private static AbstractEditingModel prepareAbstractEditingModel(IFile file, IDocument doc) {
    AbstractEditingModel model;
    String filename = file.getName();
    if (filename.equals(F_MANIFEST)) {
      model = new BundleModel(doc, true);
    } else if (filename.equals(F_FRAGMENT)) {
      model = new FragmentModel(doc, true);
    } else if (filename.equals(F_PLUGIN)) {
      model = new PluginModel(doc, true);
    } else if (filename.endsWith(F_PROPERTIES)) {
      model = new BuildModel(doc, true);
    } else {
      return null;
    }
    model.setUnderlyingResource(file);
    try {
      model.load();
      IModelTextChangeListener listener = createListener(filename, doc);
      model.addModelChangedListener(listener);
    } catch (CoreException e) {
      PDEPlugin.log(e);
    }
    return model;
  }

  private static IBaseModel prepareBundlePluginModel(IFile[] files, IDocument[] docs) {
    AbstractEditingModel[] models = new AbstractEditingModel[docs.length];
    boolean isFragment = false;
    models[F_Bi] = prepareAbstractEditingModel(files[F_Bi], docs[F_Bi]);
    if (models[F_Bi] instanceof IBundleModel) {
      isFragment = ((IBundleModel) models[F_Bi]).getBundle().getHeader(Constants.FRAGMENT_HOST) != null;
    }
    IBundlePluginModelBase pluginModel;
    if (isFragment) {
      pluginModel = new BundleFragmentModel();
    } else {
      pluginModel = new BundlePluginModel();
    }
    pluginModel.setBundleModel((IBundleModel) models[F_Bi]);
    if (files.length > F_Xi && files[F_Xi] != null) {
      models[F_Xi] = prepareAbstractEditingModel(files[F_Xi], docs[F_Xi]);
      pluginModel.setExtensionsModel((ISharedExtensionsModel) models[F_Xi]);
    }
    return pluginModel;
  }

  private static IModelTextChangeListener[] gatherListeners(IBaseModel editModel) {
    IModelTextChangeListener[] listeners = new IModelTextChangeListener[0];
    if (editModel instanceof AbstractEditingModel) {
      listeners = new IModelTextChangeListener[] { ((AbstractEditingModel) editModel).getLastTextChangeListener() };
    }
    if (editModel instanceof IBundlePluginModelBase) {
      IBundlePluginModelBase modelBase = (IBundlePluginModelBase) editModel;
      listeners = new IModelTextChangeListener[2];
      listeners[F_Bi] = gatherListener(modelBase.getBundleModel());
      listeners[F_Xi] = gatherListener(modelBase.getExtensionsModel());
      return listeners;
    }
    return listeners;
  }

  private static IModelTextChangeListener gatherListener(IBaseModel model) {
    if (model instanceof AbstractEditingModel) {
      return ((AbstractEditingModel) model).getLastTextChangeListener();
    }
    return null;
  }

  private static Display getDisplay() {
    Display display = Display.getCurrent();
    if (display == null) {
      display = Display.getDefault();
    }
    return display;
  }

}
