/*******************************************************************************
 * Copyright (c) 2008-2010 Sonatype, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *      Sonatype, Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.m2e.editor.pom;

import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.ARTIFACT_ID;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.GROUP_ID;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.PARENT;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.VERSION;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChild;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getTextValue;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.performOnDOMDocument;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.removeChild;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.removeIfNoChildElement;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.setText;
import static org.eclipse.m2e.editor.pom.FormUtils.isEmpty;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

import org.apache.maven.project.MavenProject;

import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.IMavenProjectRegistry;
import org.eclipse.m2e.core.ui.internal.actions.OpenPomAction;
import org.eclipse.m2e.core.ui.internal.dialogs.InputHistory;
import org.eclipse.m2e.core.ui.internal.editing.PomEdits;
import org.eclipse.m2e.core.ui.internal.editing.PomEdits.OperationTuple;
import org.eclipse.m2e.editor.MavenEditorImages;
import org.eclipse.m2e.editor.internal.Messages;
import org.eclipse.m2e.editor.xml.internal.FormHoverProvider;


/**
 * This class provides basic page editor functionality (event listeners, readonly, etc)
 * 
 * @author Anton Kraev
 * @author Eugene Kuleshov
 */
public abstract class MavenPomEditorPage extends FormPage {
  private static final String MODIFY_LISTENER = "MODIFY_LISTENER";

  private static final String VALUE_PROVIDER = "VALUE_PROVIDER";

  private static final Logger LOG = LoggerFactory.getLogger(MavenPomEditorPage.class);

  // parent editor
  protected final MavenPomEditor pomEditor;

  private boolean updatingModel2 = false;

  // have we loaded data?
  private boolean dataLoaded;

  private InputHistory inputHistory;

  private Action selectParentAction;

  private IModelStateListener listener;

  private boolean alreadyShown = false;

  public MavenPomEditorPage(MavenPomEditor pomEditor, String id, String title) {
    super(pomEditor, id, title);
    this.pomEditor = pomEditor;
    this.inputHistory = new InputHistory(id);
    listener = new IModelStateListener() {
      public void modelResourceMoved(IStructuredModel oldModel, IStructuredModel newModel) {
      }

      public void modelResourceDeleted(IStructuredModel model) {
      }

      public void modelReinitialized(IStructuredModel structuredModel) {
      }

      public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
      }

      public void modelChanged(IStructuredModel model) {
        if(!updatingModel2) {
          loadData();
        }
      }

      public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
      }

      public void modelAboutToBeChanged(IStructuredModel model) {
      }
    };

  }

  public MavenPomEditor getPomEditor() {
    return pomEditor;
  }

  /**
   * all edits in the editor to be channeled through this method..
   * 
   * @param operation
   * @param logger
   * @param logMessage
   */
  public final void performEditOperation(PomEdits.Operation operation, Logger logger, String logMessage) {
    try {
      updatingModel2 = true;
      PomEdits.performOnDOMDocument(new PomEdits.OperationTuple(getPomEditor().getDocument(), operation));
    } catch(Exception e) {
      logger.error(logMessage, e);
    } finally {
      updatingModel2 = false;
    }
  }

  @Override
  protected void createFormContent(IManagedForm managedForm) {
    ScrolledForm form = managedForm.getForm();
    IToolBarManager toolBarManager = form.getToolBarManager();

//    toolBarManager.add(pomEditor.showAdvancedTabsAction);

    selectParentAction = new Action(Messages.MavenPomEditorPage_action_open, MavenEditorImages.PARENT_POM) {
      public void run() {
        final String[] ret = new String[3];
        try {
          performOnDOMDocument(new OperationTuple(getPomEditor().getDocument(), document -> {
            Element parent = findChild(document.getDocumentElement(), PARENT);
            ret[0] = getTextValue(findChild(parent, GROUP_ID));
            ret[1] = getTextValue(findChild(parent, ARTIFACT_ID));
            ret[2] = getTextValue(findChild(parent, VERSION));
          }, true));
          // XXX listen to parent modification and accordingly enable/disable action
          if(!isEmpty(ret[0]) && !isEmpty(ret[1]) && !isEmpty(ret[2])) {
            new Job(Messages.MavenPomEditorPage_job_opening) {
              protected IStatus run(IProgressMonitor monitor) {
                OpenPomAction.openEditor(ret[0], ret[1], ret[2], getPomEditor().getMavenProject(), monitor);
                return Status.OK_STATUS;
              }
            }.schedule();
          }
        } catch(Exception e) {
          LOG.error("Error finding parent element", e);
        }

      }
    };
    toolBarManager.add(selectParentAction);
    updateParentAction();

    toolBarManager.add(new Action(Messages.MavenPomEditorPage_actio_refresh, MavenEditorImages.REFRESH) {
      public void run() {
        pomEditor.reload();
      }
    });

    form.updateToolBar();

    // compatibility proxy to support Eclipse 3.2
    FormUtils.decorateHeader(managedForm.getToolkit(), form.getForm());

    inputHistory.load();
  }

  public void setActive(boolean active) {
    super.setActive(active);

    doLoadData(active);
    if(active) {
      getPomEditor().getModel().addModelStateListener(listener);
    } else {
      getPomEditor().getModel().removeModelStateListener(listener);
    }
    if(active && alreadyShown) {
      loadData();
      updateParentAction();
    }
    alreadyShown = true;

    //MNGECLIPSE-2674 checkreadonly is only calculated once, no need
    // to update everytime this page gets active
    boolean readOnly = pomEditor.checkReadOnly();
    if(readOnly) {
      // only perform when readonly==true, to prevent enabling all buttons on the page.
      FormUtils.setReadonly((Composite) getPartControl(), readOnly);
    }
  }

  public boolean isReadOnly() {
    return pomEditor.checkReadOnly();
  }

  private void doLoadData(boolean active) {
    try {
      if(active && !dataLoaded) {
        dataLoaded = true;
        if(getPartControl() != null) {
          getPartControl().getDisplay().asyncExec(() -> {
            try {
              loadData();
              updateParentAction();
            } catch(Throwable e) {
              LOG.error("Error loading data", e); //$NON-NLS-1$
            }
          });
        }

      }

      //error markers have to be always updated..
      IFile pomFile = pomEditor.getPomFile();
      if(pomFile != null) {
        String text = ""; //$NON-NLS-1$
        IMarker[] markers = pomFile.findMarkers(IMavenConstants.MARKER_ID, true, IResource.DEPTH_ZERO);
        IMarker max = null;
        int maxSev = -1;
        if(markers != null) {
          for(IMarker mark : markers) {
            IMarker toAdd = max;
            int sev = mark.getAttribute(IMarker.SEVERITY, -1);
            if(sev > maxSev) {
              max = mark;
              maxSev = sev;
            } else {
              toAdd = mark;
            }
            if(toAdd != null) {
              //errors get prepended while warnings get appended.
              if(toAdd.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) {
                text = NLS.bind(Messages.MavenPomEditorPage_error_add, toAdd.getAttribute(IMarker.MESSAGE, "")) + text; //$NON-NLS-2$
              } else {
                text = text
                    + NLS.bind(Messages.MavenPomEditorPage_warning_add, toAdd.getAttribute(IMarker.MESSAGE, "")); //$NON-NLS-2$
              }
            }
          }
        }
        if(max != null) {
          String head;
          String maxText = max.getAttribute(IMarker.MESSAGE, Messages.MavenPomEditorPage_error_unknown);
          if(text.length() > 0) {
            //if we have multiple errors
            text = NLS.bind(Messages.MavenPomEditorPage_add_desc, maxText, text);
            if(markers != null) {
              String number = Integer.toString(markers.length - 1);
              head = NLS.bind(Messages.FormUtils_click_for_details2,
                  maxText.length() > FormUtils.MAX_MSG_LENGTH ? maxText.substring(0, FormUtils.MAX_MSG_LENGTH)
                      : maxText,
                  number);
            } else {
              head = maxText;
              if(head.length() > FormUtils.MAX_MSG_LENGTH) {
                head = NLS.bind(Messages.FormUtils_click_for_details, head.substring(0, FormUtils.MAX_MSG_LENGTH));
              }
            }
          } else {
            //only this one
            text = maxText;
            head = maxText;
            if(head.length() > FormUtils.MAX_MSG_LENGTH) {
              head = NLS.bind(Messages.FormUtils_click_for_details, head.substring(0, FormUtils.MAX_MSG_LENGTH));
            }
          }
          int severity;
          switch(max.getAttribute(IMarker.SEVERITY, -1)) {
            case IMarker.SEVERITY_ERROR: {
              severity = IMessageProvider.ERROR;
              break;
            }
            case IMarker.SEVERITY_WARNING: {
              severity = IMessageProvider.WARNING;
              break;
            }
            case IMarker.SEVERITY_INFO: {
              severity = IMessageProvider.INFORMATION;
              break;
            }
            default: {
              severity = IMessageProvider.NONE;
            }
          }
          setErrorMessageForMarkers(head, text, severity, markers);
        } else {
          setErrorMessageForMarkers(null, null, IMessageProvider.NONE, new IMarker[0]);
        }
      }
    } catch(final CoreException ex) {
      LOG.error(ex.getMessage(), ex);
      final String msg = ex.getMessage();
      setErrorMessageForMarkers(msg, msg, IMessageProvider.ERROR, new IMarker[0]);
    }

  }

  private void setErrorMessageForMarkers(final String msg, final String tip, final int severity,
      final IMarker[] markers) {
    if(getPartControl() != null && !getPartControl().isDisposed()) {
      getPartControl().getDisplay().asyncExec(() -> {
        if(!getManagedForm().getForm().isDisposed()) {
          FormHoverProvider.Execute runnable = FormHoverProvider.createHoverRunnable(
              getManagedForm().getForm().getShell(), markers, getPomEditor().getSourcePage().getTextViewer());
          if(runnable != null) {
            FormUtils.setMessageWithPerformer(getManagedForm().getForm(), msg, severity, runnable);
          } else {
            FormUtils.setMessageAndTTip(getManagedForm().getForm(), msg, tip, severity);
          }
        }
      });
    }
  }

  public void setErrorMessage(final String msg, final int severity) {
    if(getPartControl() != null && !getPartControl().isDisposed()) {
      getPartControl().getDisplay().asyncExec(() -> {
        if(!getManagedForm().getForm().isDisposed()) {
          FormUtils.setMessage(getManagedForm().getForm(), msg, severity);
        }
      });
    }
  }

  public boolean isAdapterForType(Object type) {
    return false;
  }

  private void updateParentAction() {
    if(selectParentAction != null) {
      final boolean[] ret = new boolean[1];
      try {
        performOnDOMDocument(new OperationTuple(getPomEditor().getDocument(), document -> {
          Element parent = findChild(document.getDocumentElement(), PARENT);
          String g = getTextValue(findChild(parent, GROUP_ID));
          String a = getTextValue(findChild(parent, ARTIFACT_ID));
          String v = getTextValue(findChild(parent, VERSION));
          ret[0] = g != null && a != null && v != null;
        }, true));
      } catch(Exception e) {
        ret[0] = false;
      }
      if(ret[0]) {
        selectParentAction.setEnabled(true);
      } else {
        selectParentAction.setEnabled(false);
      }
    }
  }

  /**
   * creates a text field/Ccombo decoration that shows the evaluated value
   * 
   * @param control
   */
  public final void createEvaluatorInfo(final Control control) {
    if(!(control instanceof Text || control instanceof CCombo)) {
      throw new IllegalArgumentException("Not a Text or CCombo");
    }
    FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault()
        .getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION);
    final ControlDecoration decoration = new ControlDecoration(control, SWT.RIGHT | SWT.TOP) {

      /* (non-Javadoc)
       * @see org.eclipse.jface.fieldassist.ControlDecoration#getDescriptionText()
       */
      @Override
      public String getDescriptionText() {
        MavenProject mp = getPomEditor().getMavenProject();
        if(mp != null) {
          return FormUtils.simpleInterpolate(mp,
              control instanceof Text ? ((Text) control).getText() : ((CCombo) control).getText());
        }
        return "Cannot interpolate expressions, not resolvable file.";
      }

    };
    decoration.setShowOnlyOnFocus(false);
    decoration.setImage(fieldDecoration.getImage());
    decoration.setShowHover(true);
    decoration.hide(); //hide and wait for the value to be set.
    decoration.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        decoration.showHoverText(decoration.getDescriptionText());
      }
    });
    ModifyListener listener = e -> {
      String text = control instanceof Text ? ((Text) control).getText() : ((CCombo) control).getText();
      if(text.indexOf("${") != -1 && text.indexOf("}") != -1) {
        decoration.show();
      } else {
        decoration.hide();
      }
    };
    if(control instanceof Text) {
      ((Text) control).addModifyListener(listener);
    } else {
      ((CCombo) control).addModifyListener(listener);
    }
    control.addMouseTrackListener(new MouseTrackListener() {
      public void mouseHover(MouseEvent e) {
        decoration.showHoverText(decoration.getDescriptionText());
      }

      public void mouseExit(MouseEvent e) {
        decoration.hideHover();
      }

      public void mouseEnter(MouseEvent e) {
      }
    });
  }

  public void dispose() {
    inputHistory.save();
    MavenPomEditor pe = getPomEditor();
    if(pe != null && pe.getModel() != null) {
      pe.getModel().removeModelStateListener(listener);
    }

    super.dispose();
  }

  public abstract void loadData();

  public void setElementValueProvider(Control control, ElementValueProvider provider) {
    control.setData(VALUE_PROVIDER, provider);
  }

  public void setModifyListener(final Control control) {
    Assert.isTrue(control instanceof CCombo || control instanceof Text || control instanceof Combo);

    ModifyListener ml = new ModifyListener() {
      String getText(Control control) {
        if(control instanceof Text) {
          return ((Text) control).getText();
        }
        if(control instanceof Combo) {
          return ((Combo) control).getText();
        }
        if(control instanceof CCombo) {
          return ((CCombo) control).getText();
        }
        throw new IllegalStateException();
      }

      public void modifyText(ModifyEvent e) {
        final ElementValueProvider provider = (ElementValueProvider) control.getData(VALUE_PROVIDER);
        if(provider == null) {
          throw new IllegalStateException("no value provider for " + control);
        }
        performEditOperation(document -> {
          String text = getText(control);
          if(isEmpty(text) || text.equals(provider.getDefaultValue())) {
            //remove value
            Element el1 = provider.find(document);
            if(el1 != null) {
              Node parent = el1.getParentNode();
              if(parent instanceof Element) {
                removeChild((Element) parent, el1);
                removeIfNoChildElement((Element) parent);
              }
            }
          } else {
            //set value and any parents..
            Element el2 = provider.get(document);
            setText(el2, text);
          }
        }, LOG, "Error updating document");
      }
    };
    control.setData(MODIFY_LISTENER, ml);
  }

  public void removeNotifyListener(Text control) {
    if(!control.isDisposed()) {
      ModifyListener listener = (ModifyListener) control.getData(MODIFY_LISTENER);
      if(listener != null) {
        control.removeModifyListener(listener);
      }
    }
  }

  public void addNotifyListener(Text control) {
    if(!control.isDisposed()) {
      ModifyListener listener = (ModifyListener) control.getData(MODIFY_LISTENER);
      if(listener != null) {
        control.addModifyListener(listener);
      }
    }
  }

  public void removeNotifyListener(CCombo control) {
    if(!control.isDisposed()) {
      ModifyListener listener = (ModifyListener) control.getData(MODIFY_LISTENER);
      if(listener != null) {
        control.removeModifyListener(listener);
      }
    }
  }

  public void addNotifyListener(CCombo control) {
    if(!control.isDisposed()) {
      ModifyListener listener = (ModifyListener) control.getData(MODIFY_LISTENER);
      if(listener != null) {
        control.addModifyListener(listener);
      }
    }
  }

  public void removeNotifyListener(Combo control) {
    if(!control.isDisposed()) {
      ModifyListener listener = (ModifyListener) control.getData(MODIFY_LISTENER);
      if(listener != null) {
        control.removeModifyListener(listener);
      }
    }
  }

  public void addNotifyListener(Combo control) {
    if(!control.isDisposed()) {
      ModifyListener listener = (ModifyListener) control.getData(MODIFY_LISTENER);
      if(listener != null) {
        control.addModifyListener(listener);
      }
    }
  }

  public IMavenProjectFacade findModuleProject(String moduleName) {
    IFile pomFile = pomEditor.getPomFile();
    if(pomFile != null) {
      return findModuleProject(pomFile, moduleName);
    }
    return null;
  }

  private IMavenProjectFacade findModuleProject(IFile pomFile, String module) {
    IPath modulePath = pomFile.getParent().getLocation();
    if(modulePath == null)
      return null;
    modulePath = modulePath.append(module);
    //it's possible to have the pom file name in the module path..
    if(!modulePath.lastSegment().endsWith("pom.xml")) { //$NON-NLS-1$
      modulePath = modulePath.append("pom.xml"); //$NON-NLS-1$
    }
    IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
    IMavenProjectFacade[] facades = projectManager.getProjects();
    for(int i = 0; i < facades.length; i++ ) {
      if(modulePath.equals(facades[i].getPom().getLocation())) {
        return facades[i];
      }
    }
    return null;
  }

  public IFile findModuleFile(String moduleName) {
    IFile pomFile = pomEditor.getPomFile();
    if(pomFile != null) {
      IPath modulePath = pomFile.getParent().getLocation();
      if(modulePath == null)
        return null;
      modulePath = modulePath.append(moduleName);
      //it's possible to have the pom file name in the module path..
      if(!modulePath.lastSegment().endsWith("pom.xml")) { //$NON-NLS-1$
        modulePath = modulePath.append("pom.xml"); //$NON-NLS-1$
      }
      IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(modulePath);
      return file;
    }
    return null;
  }

  public void initPopupMenu(Viewer viewer, String id) {
    MenuManager menuMgr = new MenuManager("#PopupMenu-" + id); //$NON-NLS-1$
    menuMgr.setRemoveAllWhenShown(true);

    Menu menu = menuMgr.createContextMenu(viewer.getControl());

    viewer.getControl().setMenu(menu);

    getEditorSite().registerContextMenu(MavenPomEditor.EDITOR_ID + id, menuMgr, viewer, false);
  }

  /**
   * Adapter for Text, Combo and CCombo widgets
   */
  public interface TextAdapter {
    String getText();

    void addModifyListener(ModifyListener listener);
  }

  public IProject getProject() {
    IFile pomFile = pomEditor.getPomFile();
    return pomFile != null ? pomFile.getProject() : null;
  }

  protected void addToHistory(Control control) {
    inputHistory.add(control);
  }

  /**
   * pages gets notified when cached effective model has changed.
   */
  public void mavenProjectHasChanged() {
  }
}
