/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hdt.ui.views;

import java.util.Collection;

import org.apache.hdt.core.cluster.HadoopCluster;
import org.apache.hdt.core.cluster.HadoopJob;
import org.apache.hdt.core.cluster.IJobListener;
import org.apache.hdt.core.cluster.utils.JarModule;
import org.apache.hdt.ui.ImageLibrary;
import org.apache.hdt.ui.actions.EditLocationAction;
import org.apache.hdt.ui.actions.NewLocationAction;
import org.apache.hdt.ui.cluster.IHadoopClusterListener;
import org.apache.hdt.ui.cluster.ServerRegistry;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.ViewPart;

/**
 * Map/Reduce locations view: displays all available Hadoop locations and the
 * Jobs running/finished on these locations
 */
public class ClusterView extends ViewPart implements ITreeContentProvider,
    ITableLabelProvider, IJobListener, IHadoopClusterListener {

  /**
   * Deletion action: delete a Hadoop location, kill a running job or remove
   * a finished job entry
   */
  class DeleteAction extends Action {

    DeleteAction() {
      setText("Delete");
      setImageDescriptor(ImageLibrary.get("server.view.action.delete"));
    }

    /* @inheritDoc */
    @Override
    public void run() {
      ISelection selection =
          getViewSite().getSelectionProvider().getSelection();
      if ((selection != null) && (selection instanceof IStructuredSelection)) {
        Object selItem =
            ((IStructuredSelection) selection).getFirstElement();

        if (selItem instanceof HadoopCluster) {
          HadoopCluster location = (HadoopCluster) selItem;
          if (MessageDialog.openConfirm(Display.getDefault()
              .getActiveShell(), "Confirm delete Hadoop location",
              "Do you really want to remove the Hadoop location: "
                  + location.getLocationName())) {
            ServerRegistry.getInstance().removeServer(location);
          }

        } else if (selItem instanceof HadoopJob) {

          // kill the job
          HadoopJob job = (HadoopJob) selItem;
          if (job.isCompleted()) {
            // Job already finished, remove the entry
            job.getLocation().purgeJob(job);

          } else {
            // Job is running, kill the job?
            if (MessageDialog.openConfirm(Display.getDefault()
                .getActiveShell(), "Confirm kill running Job",
                "Do you really want to kill running Job: " + job.getJobID())) {
              job.kill();
            }
          }
        }
      }
    }
  }

  /**
   * This object is the root content for this content provider
   */
  private static final Object CONTENT_ROOT = new Object();

  private final IAction deleteAction = new DeleteAction();

  private final IAction editServerAction = new EditLocationAction(this);

  private final IAction newLocationAction = new NewLocationAction();

  private TreeViewer viewer;

  public ClusterView() {
  }

  /* @inheritDoc */
  @Override
  public void init(IViewSite site) throws PartInitException {
    super.init(site);
  }

  /* @inheritDoc */
  @Override
  public void dispose() {
    ServerRegistry.getInstance().removeListener(this);
  }

  /**
   * Creates the columns for the view
   */
  @Override
  public void createPartControl(Composite parent) {
    Tree main =
        new Tree(parent, SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL
            | SWT.V_SCROLL);
    main.setHeaderVisible(true);
    main.setLinesVisible(false);
    main.setLayoutData(new GridData(GridData.FILL_BOTH));

    TreeColumn serverCol = new TreeColumn(main, SWT.SINGLE);
    serverCol.setText("Location");
    serverCol.setWidth(300);
    serverCol.setResizable(true);

    TreeColumn locationCol = new TreeColumn(main, SWT.SINGLE);
    locationCol.setText("Master node");
    locationCol.setWidth(185);
    locationCol.setResizable(true);

    TreeColumn stateCol = new TreeColumn(main, SWT.SINGLE);
    stateCol.setText("State");
    stateCol.setWidth(95);
    stateCol.setResizable(true);

    TreeColumn statusCol = new TreeColumn(main, SWT.SINGLE);
    statusCol.setText("Status");
    statusCol.setWidth(300);
    statusCol.setResizable(true);

    viewer = new TreeViewer(main);
    viewer.setContentProvider(this);
    viewer.setLabelProvider(this);
    viewer.setInput(CONTENT_ROOT); // don't care

    getViewSite().setSelectionProvider(viewer);
    
    getViewSite().getActionBars().setGlobalActionHandler(
        ActionFactory.DELETE.getId(), deleteAction);
    getViewSite().getActionBars().getToolBarManager().add(editServerAction);
    getViewSite().getActionBars().getToolBarManager().add(newLocationAction);

    createActions();
    createContextMenu();
  }

  /**
   * Actions
   */
  private void createActions() {
    /*
     * addItemAction = new Action("Add...") { public void run() { addItem(); } };
     * addItemAction.setImageDescriptor(ImageLibrary
     * .get("server.view.location.new"));
     */
    /*
     * deleteItemAction = new Action("Delete") { public void run() {
     * deleteItem(); } };
     * deleteItemAction.setImageDescriptor(getImageDescriptor("delete.gif"));
     * 
     * selectAllAction = new Action("Select All") { public void run() {
     * selectAll(); } };
     */
    // Add selection listener.
    viewer.addSelectionChangedListener(new ISelectionChangedListener() {
      public void selectionChanged(SelectionChangedEvent event) {
        updateActionEnablement();
      }
    });
  }

  private void addItem() {
    System.out.printf("ADD ITEM\n");
  }

  private void updateActionEnablement() {
    IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
    // deleteItemAction.setEnabled(sel.size() > 0);
  }

  /**
   * Contextual menu
   */
  private void createContextMenu() {
    // Create menu manager.
    MenuManager menuMgr = new MenuManager();
    menuMgr.setRemoveAllWhenShown(true);
    menuMgr.addMenuListener(new IMenuListener() {
      public void menuAboutToShow(IMenuManager mgr) {
        fillContextMenu(mgr);
      }
    });

    // Create menu.
    Menu menu = menuMgr.createContextMenu(viewer.getControl());
    viewer.getControl().setMenu(menu);

    // Register menu for extension.
    getSite().registerContextMenu(menuMgr, viewer);
  }

  private void fillContextMenu(IMenuManager mgr) {
    mgr.add(newLocationAction);
    mgr.add(editServerAction);
    mgr.add(deleteAction);
    /*
     * mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
     * mgr.add(deleteItemAction); mgr.add(new Separator());
     * mgr.add(selectAllAction);
     */
  }

  /* @inheritDoc */
  @Override
  public void setFocus() {

  }

  /*
   * IHadoopServerListener implementation
   */

  /* @inheritDoc */
  public void serverChanged(HadoopCluster location, int type) {
    Display.getDefault().syncExec(new Runnable() {
      public void run() {
        ClusterView.this.viewer.refresh();
      }
    });
  }

  /*
   * IStructuredContentProvider implementation
   */

  /* @inheritDoc */
  public void inputChanged(final Viewer viewer, Object oldInput,
      Object newInput) {
    if (oldInput == CONTENT_ROOT)
      ServerRegistry.getInstance().removeListener(this);
    if (newInput == CONTENT_ROOT)
      ServerRegistry.getInstance().addListener(this);
  }

  /**
   * The root elements displayed by this view are the existing Hadoop
   * locations
   */
  /* @inheritDoc */
  public Object[] getElements(Object inputElement) {
    return ServerRegistry.getInstance().getServers().toArray();
  }

  /*
   * ITreeStructuredContentProvider implementation
   */

  /**
   * Each location contains a child entry for each job it runs.
   */
  /* @inheritDoc */
  public Object[] getChildren(Object parent) {

    if (parent instanceof HadoopCluster) {
      HadoopCluster location = (HadoopCluster) parent;
      location.addJobListener(this);
      Collection<HadoopJob> jobs = location.getJobs();
      return jobs.toArray();
    }

    return null;
  }

  /* @inheritDoc */
  public Object getParent(Object element) {
    if (element instanceof HadoopCluster) {
      return CONTENT_ROOT;

    } else if (element instanceof HadoopJob) {
      return ((HadoopJob) element).getLocation();
    }

    return null;
  }

  /* @inheritDoc */
  public boolean hasChildren(Object element) {
    /* Only server entries have children */
    return (element instanceof HadoopCluster);
  }

  /*
   * ITableLabelProvider implementation
   */

  /* @inheritDoc */
  public void addListener(ILabelProviderListener listener) {
    // no listeners handling
  }

  public boolean isLabelProperty(Object element, String property) {
    return false;
  }

  /* @inheritDoc */
  public void removeListener(ILabelProviderListener listener) {
    // no listener handling
  }

  /* @inheritDoc */
  public Image getColumnImage(Object element, int columnIndex) {
    if ((columnIndex == 0) && (element instanceof HadoopCluster)) {
      return ImageLibrary.getImage("server.view.location.entry");

    } else if ((columnIndex == 0) && (element instanceof HadoopJob)) {
      return ImageLibrary.getImage("server.view.job.entry");
    }
    return null;
  }

  /* @inheritDoc */
  public String getColumnText(Object element, int columnIndex) {
    if (element instanceof HadoopCluster) {
      HadoopCluster server = (HadoopCluster) element;

      switch (columnIndex) {
        case 0:
          return server.getLocationName();
        case 1:
          return server.getMasterHostName().toString();
        case 2:
          return server.getState();
        case 3:
          return "";
      }
    } else if (element instanceof HadoopJob) {
      HadoopJob job = (HadoopJob) element;

      switch (columnIndex) {
        case 0:
          return job.getJobID().toString();
        case 1:
          return "";
        case 2:
          return job.getState().toString();
        case 3:
          return job.getStatus();
      }
    } else if (element instanceof JarModule) {
      JarModule jar = (JarModule) element;

      switch (columnIndex) {
        case 0:
          return jar.toString();
        case 1:
          return "Publishing jar to server..";
        case 2:
          return "";
      }
    }

    return null;
  }

  /*
   * IJobListener (Map/Reduce Jobs listener) implementation
   */

  /* @inheritDoc */
  public void jobAdded(HadoopJob job) {
    viewer.refresh();
  }

  /* @inheritDoc */
  public void jobRemoved(HadoopJob job) {
    viewer.refresh();
  }

  /* @inheritDoc */
  public void jobChanged(HadoopJob job) {
    viewer.refresh(job);
  }

  /* @inheritDoc */
  public void publishDone(JarModule jar) {
    viewer.refresh();
  }

  /* @inheritDoc */
  public void publishStart(JarModule jar) {
    viewer.refresh();
  }

  /*
   * Miscellaneous
   */

  /**
   * Return the currently selected server (null if there is no selection or
   * if the selection is not a server)
   * 
   * @return the currently selected server entry
   */
  public HadoopCluster getSelectedServer() {
    ITreeSelection selection = (ITreeSelection) viewer.getSelection();
    Object first = selection.getFirstElement();
    if (first instanceof HadoopCluster) {
      return (HadoopCluster) first;
    }
    return null;
  }

}
