/**
 * 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.hadoop.eclipse.servers;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.eclipse.Activator;
import org.apache.hadoop.eclipse.ErrorMessageDialog;
import org.apache.hadoop.eclipse.server.HadoopServer;
import org.apache.hadoop.eclipse.server.JarModule;
import org.apache.hadoop.mapred.JobConf;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

/**
 * Wizard for publishing a job to a Hadoop server.
 */

public class RunOnHadoopWizard extends Wizard {

  private MainWizardPage mainPage;

  private HadoopLocationWizard createNewPage;

  /**
   * The file resource (containing a main()) to run on the Hadoop location
   */
  private IFile resource;

  /**
   * The launch configuration to update
   */
  private ILaunchConfigurationWorkingCopy iConf;

  private IProgressMonitor progressMonitor;

  public RunOnHadoopWizard(IFile resource,
      ILaunchConfigurationWorkingCopy iConf) {
    this.resource = resource;
    this.iConf = iConf;
    setForcePreviousAndNextButtons(true);
    setNeedsProgressMonitor(true);
    setWindowTitle("Run on Hadoop");
  }

  /**
   * This wizard contains 2 pages:
   * <li> the first one lets the user choose an already existing location
   * <li> the second one allows the user to create a new location, in case it
   * does not already exist
   */
  /* @inheritDoc */
  @Override
  public void addPages() {
    addPage(this.mainPage = new MainWizardPage());
    addPage(this.createNewPage = new HadoopLocationWizard());
  }

  /**
   * Performs any actions appropriate in response to the user having pressed
   * the Finish button, or refuse if finishing now is not permitted.
   */
  /* @inheritDoc */
  @Override
  public boolean performFinish() {

    /*
     * Create a new location or get an existing one
     */
    HadoopServer location = null;
    if (mainPage.createNew.getSelection()) {
      location = createNewPage.performFinish();

    } else if (mainPage.table.getSelection().length == 1) {
      location = (HadoopServer) mainPage.table.getSelection()[0].getData();
    }

    if (location == null)
      return false;

    /*
     * Get the base directory of the plug-in for storing configurations and
     * JARs
     */
    File baseDir = Activator.getDefault().getStateLocation().toFile();

    // Package the Job into a JAR
    File jarFile = JarModule.createJarPackage(resource);
    if (jarFile == null) {
      ErrorMessageDialog.display("Run on Hadoop",
          "Unable to create or locate the JAR file for the Job");
      return false;
    }

    /*
     * Generate a temporary Hadoop configuration directory and add it to the
     * classpath of the launch configuration
     */

    File confDir;
    try {
      confDir = File.createTempFile("hadoop-conf-", "", baseDir);
      confDir.delete();
      confDir.mkdirs();
      if (!confDir.isDirectory()) {
        ErrorMessageDialog.display("Run on Hadoop",
            "Cannot create temporary directory: " + confDir);
        return false;
      }
    } catch (IOException ioe) {
      ioe.printStackTrace();
      return false;
    }

    // Prepare the Hadoop configuration
    JobConf conf = new JobConf(location.getConfiguration());
    conf.setJar(jarFile.getAbsolutePath());

    // Write it to the disk file
    try {
      // File confFile = File.createTempFile("hadoop-site-", ".xml",
      // confDir);
      File confFile = new File(confDir, "hadoop-site.xml");
      FileOutputStream fos = new FileOutputStream(confFile);
      conf.writeXml(fos);
      fos.close();

    } catch (IOException ioe) {
      ioe.printStackTrace();
      return false;
    }

    // Setup the Launch class path
    List<String> classPath;
    try {
      classPath =
          iConf.getAttribute(
              IJavaLaunchConfigurationConstants.ATTR_CLASSPATH,
              new ArrayList());
      IPath confIPath = new Path(confDir.getAbsolutePath());
      IRuntimeClasspathEntry cpEntry =
          JavaRuntime.newArchiveRuntimeClasspathEntry(confIPath);
      classPath.add(0, cpEntry.getMemento());
      iConf.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH,
          classPath);

    } catch (CoreException e) {
      e.printStackTrace();
      return false;
    }

    // location.runResource(resource, progressMonitor);
    return true;
  }

  private void refreshButtons() {
    getContainer().updateButtons();
  }

  /**
   * Allows finish when an existing server is selected or when a new server
   * location is defined
   */
  /* @inheritDoc */
  @Override
  public boolean canFinish() {
    if (mainPage != null)
      return mainPage.canFinish();
    return false;
  }

  /**
   * This is the main page of the wizard. It allows the user either to choose
   * an already existing location or to indicate he wants to create a new
   * location.
   */
  public class MainWizardPage extends WizardPage {

    private Button createNew;

    private Table table;

    private Button chooseExisting;

    public MainWizardPage() {
      super("Select or define server to run on");
      setTitle("Select Hadoop location");
      setDescription("Select a Hadoop location to run on.");
    }

    /* @inheritDoc */
    @Override
    public boolean canFlipToNextPage() {
      return createNew.getSelection();
    }

    /* @inheritDoc */
    public void createControl(Composite parent) {
      Composite panel = new Composite(parent, SWT.NONE);
      panel.setLayout(new GridLayout(1, false));

      // Label
      Label label = new Label(panel, SWT.NONE);
      label.setText("Select a Hadoop Server to run on.");
      GridData gData = new GridData(GridData.FILL_BOTH);
      gData.grabExcessVerticalSpace = false;
      label.setLayoutData(gData);

      // Create location button
      createNew = new Button(panel, SWT.RADIO);
      createNew.setText("Define a new Hadoop server location");
      createNew.setLayoutData(gData);
      createNew.addSelectionListener(new SelectionListener() {
        public void widgetDefaultSelected(SelectionEvent e) {
        }

        public void widgetSelected(SelectionEvent e) {
          setPageComplete(true);
          RunOnHadoopWizard.this.refreshButtons();
        }
      });
      createNew.setSelection(true);

      // Select existing location button
      chooseExisting = new Button(panel, SWT.RADIO);
      chooseExisting
          .setText("Choose an existing server from the list below");
      chooseExisting.setLayoutData(gData);
      chooseExisting.addSelectionListener(new SelectionListener() {
        public void widgetDefaultSelected(SelectionEvent e) {
        }

        public void widgetSelected(SelectionEvent e) {
          if (chooseExisting.getSelection()
              && (table.getSelectionCount() == 0)) {
            if (table.getItems().length > 0) {
              table.setSelection(0);
            }
          }
          RunOnHadoopWizard.this.refreshButtons();
        }
      });

      // Table of existing locations
      Composite serverListPanel = new Composite(panel, SWT.FILL);
      gData = new GridData(GridData.FILL_BOTH);
      gData.horizontalSpan = 1;
      serverListPanel.setLayoutData(gData);

      FillLayout layout = new FillLayout();
      layout.marginHeight = layout.marginWidth = 12;
      serverListPanel.setLayout(layout);

      table =
          new Table(serverListPanel, SWT.BORDER | SWT.H_SCROLL
              | SWT.V_SCROLL | SWT.FULL_SELECTION);
      table.setHeaderVisible(true);
      table.setLinesVisible(true);

      TableColumn nameColumn = new TableColumn(table, SWT.LEFT);
      nameColumn.setText("Location");
      nameColumn.setWidth(450);

      TableColumn hostColumn = new TableColumn(table, SWT.LEFT);
      hostColumn.setText("Master host name");
      hostColumn.setWidth(250);

      // If the user select one entry, switch to "chooseExisting"
      table.addSelectionListener(new SelectionListener() {
        public void widgetDefaultSelected(SelectionEvent e) {
        }

        public void widgetSelected(SelectionEvent e) {
          chooseExisting.setSelection(true);
          createNew.setSelection(false);
          setPageComplete(table.getSelectionCount() == 1);
          RunOnHadoopWizard.this.refreshButtons();
        }
      });

      TableViewer viewer = new TableViewer(table);
      HadoopServerSelectionListContentProvider provider =
          new HadoopServerSelectionListContentProvider();
      viewer.setContentProvider(provider);
      viewer.setLabelProvider(provider);
      viewer.setInput(new Object());
      // don't care, get from singleton server registry

      this.setControl(panel);
    }

    /**
     * Returns whether this page state allows the Wizard to finish or not
     * 
     * @return can the wizard finish or not?
     */
    public boolean canFinish() {
      if (!isControlCreated())
        return false;

      if (this.createNew.getSelection())
        return getNextPage().isPageComplete();

      return this.chooseExisting.getSelection();
    }
  }

  /**
   * @param progressMonitor
   */
  public void setProgressMonitor(IProgressMonitor progressMonitor) {
    this.progressMonitor = progressMonitor;
  }
}
