/*******************************************************************************
 * Copyright (c) 2004, 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 Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060329   128069 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060418   136180 kathy@ca.ibm.com - Kathy Chan
 * 20060524   141194 joan@ca.ibm.com - Joan Haggarty
 * 20060825   135570 makandre@ca.ibm.com - Andrew Mak, Service implementation URL not displayed properly on first page
 * 20080212   208795 ericdp@ca.ibm.com - Eric Peters, WS wizard framework should support EJB 3.0
 * 20080229   218696 ericdp@ca.ibm.com - Eric D. Peters, APIs using EJBArtifactEdit not able to deal with some EJB 3.0 beans properly
 * 20080428   224726 pmoogk@ca.ibm.com - Peter Moogk
 *******************************************************************************/
package org.eclipse.jst.ws.internal.consumption.ui.widgets.object;

import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EJBResource;
import org.eclipse.jst.j2ee.ejb.Session;
import org.eclipse.jst.j2ee.ejb.componentcore.util.EJBArtifactEdit;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.javaee.ejb.EnterpriseBeans;
import org.eclipse.jst.javaee.ejb.SessionBean;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages;
import org.eclipse.jst.ws.internal.consumption.ui.plugin.WebServiceConsumptionUIPlugin;
import org.eclipse.jst.ws.internal.ui.common.UIUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;

public class EJBSelectionWidget extends AbstractObjectSelectionWidget implements IObjectSelectionWidget
{

  private Combo earList;
  private EJBTableViewer beanList;
  private IVirtualComponent[] earComponents;
  private Integer selectedBeanIndex = null;
  private Vector ejbBeanNames;
  private Vector ejbComponentNames;
  private Vector ejbComponentProjectNames;
  private Hashtable ejbValuesByEARSelectionCache;
  private Listener  statusListener_;
  private String displayString_ = "";
  /* CONTEXT_ID PEBD0001 for the EAR Projects drop-down box */
  private String INFOPOP_PEBD_EAR_PROJECTS = "PEBD0001";
  /* CONTEXT_ID PEBD0002 for the table containing all of the bean names */
  private String INFOPOP_PEBD_TABLE_BEAN_NAMES = "PEBD0002";

  public EJBSelectionWidget()
  {
	earComponents = J2EEUtils.getAllEARComponents();
    ejbValuesByEARSelectionCache = new Hashtable();
  }

  public String getSelectedBean()
  {
    if (selectedBeanIndex != null)
    {
      return (String) (ejbBeanNames.elementAt(selectedBeanIndex.intValue()));
    }
    return null;
  }

  public String getSelectedProject()
  {
    if (selectedBeanIndex != null)
    {
      return (String) (ejbComponentProjectNames.elementAt(selectedBeanIndex.intValue()));
    }
    return null;
  }

  public WidgetDataEvents addControls(Composite parent, Listener statusListener)
  {
    statusListener_  = statusListener;
    UIUtils utils = new UIUtils( WebServiceConsumptionUIPlugin.ID );
    
    Composite composite = utils.createComposite(parent, 1, 0, 0);
    
    Composite projectComposite = utils.createComposite(composite, 2);
    new Label(projectComposite, SWT.NULL).setText(ConsumptionUIMessages.LABEL_EAR_PROJECTS);
    earList = new Combo(projectComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
    earList.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    earList.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent evt)
      {
        Combo widget = (Combo) (evt.widget);
        int earListSelectionIndex = widget.getSelectionIndex();
        if (earListSelectionIndex > 0)
        {
          setBeanList(earComponents[earListSelectionIndex-1]);
        }
        else
        {
          setBeanList(null);
        }
        selectedBeanIndex = null;
        statusListener_.handleEvent(null);
      }
    });
    addEARNamesToList();
    earList.setToolTipText(ConsumptionUIMessages.TOOLTIP_EAR_PROJECTS);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(earList, INFOPOP_PEBD_EAR_PROJECTS);
    
    Group beanComposite = utils.createGroup(composite, ConsumptionUIMessages.LABEL_EJB_BEAN_NAME, "", "");
    beanList = new EJBTableViewer(beanComposite);    
    Table beanTable = beanList.getTable();
    GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
    gd.heightHint = 100;
    beanTable.setLayoutData(gd);
    beanTable.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent evt)
      {
        Table table = (Table) (evt.widget);
        selectedBeanIndex = new Integer(table.getSelectionIndex());
        statusListener_.handleEvent(null);
      }
    });
    beanTable.setToolTipText(ConsumptionUIMessages.TOOLTIP_TABLE_BEAN_NAMES);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(beanTable, INFOPOP_PEBD_TABLE_BEAN_NAMES);
    
    if (earComponents != null && earComponents.length > 0)
    {
      setBeanList(earComponents[0]);
    }
    else
    {
      setBeanList(null);
    }
    
    // This is a dummy label that forces the status label into the second
    // column.
    new Label(composite, SWT.NULL).setText("");
   
    return this;
  }

  
  
  private void addEARNamesToList()
  {
    earList.add(ConsumptionUIMessages.LABEL_SHOW_ALL_STATELESS_SESSION_EJBS);
    if (earComponents != null && earComponents.length > 0)
    {
      for (int index = 0; index < earComponents.length; index++)
      {
        earList.add(earComponents[index].getName());
      }
      earList.setText(earList.getItem(1));
    }
  }

  private void setBeanList(IVirtualComponent earComponent)
  {    
    String cacheKey = (earComponent == null)? earList.getItem(0): earComponent.getName();
    
    //Check if we've already cached results for this case. If so, use the
    //cached values and return. If not, continue.
    EJBTableValues cachedValues = (EJBTableValues)ejbValuesByEARSelectionCache.get(cacheKey);
    if (cachedValues != null)
    {
      ejbBeanNames = cachedValues.cachedEjbBeanNames;
      ejbComponentNames = cachedValues.cachedEjbComponentNames;
      ejbComponentProjectNames = cachedValues.cachdedEjbComponentProjectNames;
      beanList.setData(ejbBeanNames, ejbComponentNames);
      beanList.setInput(ejbBeanNames);    
      return;
    }
    
    IVirtualComponent[] ejbComponentsArray = null;
    if (earComponent == null)
    {  
      ejbComponentsArray = J2EEUtils.getAllEJBComponents();      
    }
    else
    {
      ejbComponentsArray = J2EEUtils.getReferencingEJBComponentsFromEAR(earComponent.getProject());
    }
    
    Table beanTable = beanList.getTable();
    beanTable.removeAll();
    ejbBeanNames = new Vector();
    ejbComponentNames = new Vector();
    ejbComponentProjectNames = new Vector();
    for (int index = 0; index < ejbComponentsArray.length; index++)
    {
    	IProject project = ejbComponentsArray[index].getProject();
        Vector beans = J2EEUtils.getBeanNames(project);
        String componentName = ejbComponentsArray[index].getName();
        String projectName = ejbComponentsArray[index].getProject().getName();
        ejbBeanNames.addAll(beans);
        ejbComponentNames.addAll(Collections.nCopies(beans.size(), componentName));
        ejbComponentProjectNames.addAll(Collections.nCopies(beans.size(), projectName));                
   
    }
    beanList.setData(ejbBeanNames, ejbComponentNames);
    beanList.setInput(ejbBeanNames);
    
    //Cache the results for next time
    EJBTableValues ejbTableValues = new EJBTableValues();
    ejbTableValues.cachedEjbBeanNames = ejbBeanNames;
    ejbTableValues.cachedEjbComponentNames = ejbComponentNames;
    ejbTableValues.cachdedEjbComponentProjectNames = ejbComponentProjectNames;
    ejbValuesByEARSelectionCache.put(cacheKey, ejbTableValues);        
  }
    
  public void setInitialSelection(IStructuredSelection initialSelection)
  {
    if (initialSelection != null && !initialSelection.isEmpty())
    {
      Object object = initialSelection.getFirstElement();
      if (object instanceof Session)
      {
        Session session = (Session) object;
        EJBJar jar = session.getEjbJar();
        if (jar != null)
        {
          for (int i = 0; i < earComponents.length; i++)
          {
			      IVirtualComponent[] ejbComponents = J2EEUtils.getReferencingEJBComponentsFromEAR(earComponents[i].getProject());
			      for (int j=0; j <ejbComponents.length; j++)
			      {
              EJBArtifactEdit  ejbEdit = null;
              try {
                ejbEdit = EJBArtifactEdit.getEJBArtifactEditForRead(ejbComponents[j]);
                EJBResource ejbRes = ejbEdit.getEJBJarXmiResource();
                if (ejbRes.getEJBJar() == jar)
                {
                  earList.setText(earComponents[i].getName());
                  setBeanList(earComponents[i]);
                  beanList.setSelection(new StructuredSelection(new Integer[]{new Integer(ejbBeanNames.indexOf(session.getName()))}));
                  selectedBeanIndex = new Integer(ejbBeanNames.indexOf(session.getName()));
                  return;
                }                

              }
              finally {
                if (ejbEdit!=null)
                  ejbEdit.dispose();
              }
				
			      }
          }
          
          //Haven't returned yet so we did not find an EAR that contains this EJB. Initialize the page accordingly.
          earList.setText(earList.getItem(0));
          setBeanList(null);
          beanList.setSelection(new StructuredSelection(new Integer[]{new Integer(ejbBeanNames.indexOf(session.getName()))}));
          selectedBeanIndex = new Integer(ejbBeanNames.indexOf(session.getName()));
        }
      }
      else if (object instanceof String)
    	  displayString_ = (String) object; // save for display use
    }
  }

  public IStructuredSelection getObjectSelection()
  {
		String selEJBName = (String) ejbBeanNames.get(selectedBeanIndex
				.intValue());
		if (selEJBName != null) {
			// Get the project containing the bean to get the corresponding
			// Session object.
			// Then return the Session object in an IStructuredSelection.
			String ejbComponentName = (String) ejbComponentNames
					.get(selectedBeanIndex.intValue());
			IVirtualComponent ejbComponent = ComponentUtilities
					.getComponent(ejbComponentName);
			IProject project = ejbComponent.getProject();
			IModelProvider provider = ModelProviderManager
					.getModelProvider(project);
			Object modelObject = provider.getModelObject();
			List sessions = new Vector();
			boolean isJ2EE5 = J2EEProjectUtilities.isJEEProject(project);
			if (isJ2EE5) {
	    		//a JEE5 project
	    		EnterpriseBeans eBeans = ((org.eclipse.jst.javaee.ejb.EJBJar)modelObject).getEnterpriseBeans();
	    		if (eBeans !=null)
	    			sessions = eBeans.getSessionBeans();
			} else {
				sessions = ((EJBJar) modelObject).getSessionBeans();
			}
			for (Iterator it2 = sessions.iterator(); it2.hasNext();) {
				Object next = (it2.next());
				if (isJ2EE5) {
					SessionBean session = (SessionBean) next;
					if (selEJBName.equals(session.getEjbName()))
						return new StructuredSelection(
								new SessionBean[] { session });

				} else {
					Session session = (Session) next;
					if (selEJBName.equals(session.getName()))
						return new StructuredSelection(
								new Session[] { session });
				}

			}
		}
		return new StructuredSelection(new Object[0]);
	}
  
  public IProject getProject()
  {
    String projectName = getSelectedProject();
    if (projectName != null && projectName.length() > 0)
      return ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
    else
      return null;
  }
  
  public String getComponentName()
  {
    if (selectedBeanIndex != null)
    {
      return (String) (ejbComponentNames.elementAt(selectedBeanIndex.intValue()));
    }
    return null;
  }    
  
  public String getObjectSelectionDisplayableString() {
	  
	  if (ejbBeanNames == null)
		  return displayString_;
	  
	  int index = selectedBeanIndex == null ? 0 : selectedBeanIndex.intValue();
	  String bean = (String) ejbBeanNames.get(index);
	  return bean == null ? displayString_ : bean;
  }
  
  public IStatus validateSelection(IStructuredSelection objectSelection)
  {
    return Status.OK_STATUS;
  }
  
  public IStatus getStatus()
  {  	
    if (selectedBeanIndex == null)
    {
    	return StatusUtils.errorStatus( "" );
    }
    
  	return Status.OK_STATUS;
  }
  
  public Point getWidgetSize() {
	return new Point(450, 350);
  } 
    
  private class EJBTableValues
  {
    Vector cachedEjbBeanNames;
    Vector cachedEjbComponentNames;
    Vector cachdedEjbComponentProjectNames; 
  }
  
}
