/*******************************************************************************
 * Copyright (c) 2004 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
 *******************************************************************************/
package org.eclipse.wst.ws.internal.explorer.platform.uddi.perspective;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import javax.servlet.ServletContext;
import org.eclipse.wst.ws.internal.datamodel.BasicModel;
import org.eclipse.wst.ws.internal.datamodel.Model;
import org.eclipse.wst.ws.internal.explorer.favorites.FavoritesRegistryTypeDefault;
import org.eclipse.wst.ws.internal.explorer.platform.constants.ActionInputs;
import org.eclipse.wst.ws.internal.explorer.platform.datamodel.TreeElement;
import org.eclipse.wst.ws.internal.explorer.platform.favorites.actions.AddRegistryToUDDIPerspectiveAction;
import org.eclipse.wst.ws.internal.explorer.platform.favorites.datamodel.FavoritesMainElement;
import org.eclipse.wst.ws.internal.explorer.platform.favorites.datamodel.FavoritesUDDIRegistryElement;
import org.eclipse.wst.ws.internal.explorer.platform.favorites.datamodel.FavoritesUDDIRegistryFolderElement;
import org.eclipse.wst.ws.internal.explorer.platform.perspective.Controller;
import org.eclipse.wst.ws.internal.explorer.platform.perspective.Node;
import org.eclipse.wst.ws.internal.explorer.platform.perspective.NodeManager;
import org.eclipse.wst.ws.internal.explorer.platform.perspective.Perspective;
import org.eclipse.wst.ws.internal.explorer.platform.uddi.actions.OpenRegistryAction;
import org.eclipse.wst.ws.internal.explorer.platform.uddi.actions.RegFindServiceUUIDAction;
import org.eclipse.wst.ws.internal.explorer.platform.uddi.actions.SwitchPerspectiveFromUDDIAction;
import org.eclipse.wst.ws.internal.explorer.platform.uddi.constants.UDDIActionInputs;
import org.eclipse.wst.ws.internal.explorer.platform.uddi.datamodel.CategoryModel;
import org.eclipse.wst.ws.internal.explorer.platform.uddi.datamodel.RegistryElement;
import org.eclipse.wst.ws.internal.explorer.platform.uddi.datamodel.UDDIMainElement;
import org.eclipse.wst.ws.internal.explorer.platform.util.DirUtils;
import org.eclipse.wst.ws.internal.explorer.platform.util.URLUtils;
import org.eclipse.wst.ws.internal.explorer.platform.util.Validator;
import org.eclipse.wst.ws.internal.parser.favorites.IFavoritesUDDIRegistry;
import org.uddi4j.datatype.tmodel.TModel;

public class UDDIPerspective extends Perspective
{
  private Hashtable knownRegistries_;
  private IFavoritesUDDIRegistry ibmPublicUDDITestRegistry_;
  private Model navigatorModel_;
  private NodeManager navigatorManager_;
  private int wsdlType_;
  private Hashtable categoryManagers_;
  String categoryTModelKey_;
  
  // Window sizes
  private String perspectiveContentFramesetCols_;
  private String savedPerspectiveContentFramesetCols_;
  private String actionsContainerFramesetRows_;
  private String savedActionsContainerFramesetRows_;

  private final String IBM_TEST_REG_INQUIRY_URL = "http://uddi.ibm.com/testregistry/inquiryapi";
  private final String IBM_TEST_REG_PUBLISH_URL = "https://uddi.ibm.com/testregistry/publishapi";

  public UDDIPerspective(Controller controller)
  {
    super("uddi",controller);
  }

  public final void initPerspective(ServletContext application)
  {
    String defaultFavorites = controller_.getDefaultFavoritesLocation();
	FavoritesRegistryTypeDefault favRegTypeDefault = new FavoritesRegistryTypeDefault(defaultFavorites);
    IFavoritesUDDIRegistry[] favRegistriesDefault = favRegTypeDefault.getFavoritesUDDIRegistries();
    knownRegistries_ = new Hashtable();
    for (int i=0;i<favRegistriesDefault.length;i++)
    {
      if (favRegistriesDefault[i].getInquiryURL().equals(IBM_TEST_REG_INQUIRY_URL) && favRegistriesDefault[i].getPublishURL().equals(IBM_TEST_REG_PUBLISH_URL))
        ibmPublicUDDITestRegistry_ = favRegistriesDefault[i];
      knownRegistries_.put(favRegistriesDefault[i].getInquiryURL(),favRegistriesDefault[i]);
    }
    if (ibmPublicUDDITestRegistry_ == null && favRegistriesDefault.length > 0)
      ibmPublicUDDITestRegistry_ = favRegistriesDefault[0];
    
    navigatorModel_ = new BasicModel("uddiModel");
    UDDIMainElement uddiMainElement = new UDDIMainElement(getMessage("NODE_NAME_UDDI_MAIN"),navigatorModel_);
    navigatorModel_.setRootElement(uddiMainElement);
    navigatorManager_ = new NodeManager(controller_);
    UDDIMainNode uddiMainNode = new UDDIMainNode(uddiMainElement,navigatorManager_);
    navigatorManager_.setRootNode(uddiMainNode);

    wsdlType_ = UDDIActionInputs.WSDL_TYPE_SERVICE_INTERFACE;
    categoryManagers_ = new Hashtable();
    
    // Initialize the default category models.
    if (application.getAttribute("commonCategoryModels") == null)
    {
      synchronized (application)
      {
        if (application.getAttribute("commonCategoryModels") == null)
        {
          Hashtable commonCategoryModels = new Hashtable();
		  
          CategoryModel naicsModel = new CategoryModel();
          naicsModel.setServletContext(application);
          naicsModel.setDefaultDataFile("/uddi/data/naics-data.txt");
          naicsModel.setDisplayName(getMessage("FORM_OPTION_CATEGORY_NAICS"));
          naicsModel.setTModelKey(TModel.NAICS_TMODEL_KEY);
          commonCategoryModels.put(TModel.NAICS_TMODEL_KEY,naicsModel);
          
          CategoryModel unspscModel = new CategoryModel();
		  unspscModel.setServletContext(application);
          unspscModel.setDefaultDataFile("/uddi/data/unspsc-data.txt");
          unspscModel.setDisplayName(getMessage("FORM_OPTION_CATEGORY_UNSPSC_73"));
          unspscModel.setTModelKey(TModel.UNSPSC_73_TMODEL_KEY);
          commonCategoryModels.put(TModel.UNSPSC_73_TMODEL_KEY,unspscModel);
          
          CategoryModel geoModel = new CategoryModel();
		  geoModel.setServletContext(application);
          geoModel.setDefaultDataFile("/uddi/data/geo-data.txt");
          geoModel.setDisplayName(getMessage("FORM_OPTION_CATEGORY_GEO"));
          geoModel.setTModelKey(TModel.ISO_CH_TMODEL_KEY);
          commonCategoryModels.put(TModel.ISO_CH_TMODEL_KEY,geoModel);
          
          application.setAttribute("commonCategoryModels",commonCategoryModels);
        }
      }
    }
    categoryTModelKey_ = null;
    
    // Starting frameset sizes.
    if (!DirUtils.isRTL())
      perspectiveContentFramesetCols_ = "30%,*";
    else
      perspectiveContentFramesetCols_ = "*,30%";
    savedPerspectiveContentFramesetCols_ = perspectiveContentFramesetCols_;
    actionsContainerFramesetRows_ = "75%,*";
    savedActionsContainerFramesetRows_ = actionsContainerFramesetRows_;
  }
  
  public final Hashtable getKnownRegistries()
  {
    // We must always query the favorites to see if additional registries were added over time. This property cannot be cached.
    FavoritesMainElement favMainElement = (FavoritesMainElement)(controller_.getFavoritesPerspective().getNodeManager().getRootNode().getTreeElement());
    FavoritesUDDIRegistryFolderElement favRegFolderElement = favMainElement.getFavoritesUDDIRegistryFolderElement();
    Enumeration e = favRegFolderElement.getAllFavorites();
    while (e.hasMoreElements())
    {
      FavoritesUDDIRegistryElement favRegElement = (FavoritesUDDIRegistryElement)e.nextElement();
      String inquiryURL = favRegElement.getInquiryURL();
      if (knownRegistries_.get(inquiryURL) == null)
        knownRegistries_.put(inquiryURL,favRegElement.getIFavoritesUDDIRegistryInterface());
    }
    return knownRegistries_;
  }

  public final String getKnownRegistryPublishURL(String inquiryURL)
  {
    IFavoritesUDDIRegistry knownRegistry = (IFavoritesUDDIRegistry)getKnownRegistries().get(inquiryURL);
    if (knownRegistry != null)
    {
      String publishURL = knownRegistry.getPublishURL();
      if (Validator.validateURL(publishURL))
        return publishURL;
    }
    return null;
  }

  public final String getKnownRegistryRegistrationURL(String inquiryURL)
  {
    IFavoritesUDDIRegistry knownRegistry = (IFavoritesUDDIRegistry)getKnownRegistries().get(inquiryURL);
    if (knownRegistry != null)
    {
      String registrationURL = knownRegistry.getRegistrationURL();
      if (Validator.validateURL(registrationURL))
        return registrationURL;
    }
    return null;    
  }

  public final IFavoritesUDDIRegistry getIBMPublicUDDITestRegistry()
  {
    return ibmPublicUDDITestRegistry_;
  }
  
  public final void preloadUDDIRegistries(String[] inquiryURLs, String[] publishURLs)
  {
    if (inquiryURLs != null)
    {
      Hashtable knownRegistries = getKnownRegistries();
      StringBuffer directoryBuffer = new StringBuffer();
      for (int i = 0; i < inquiryURLs.length; i++)
      {
		String inquiryURL = URLUtils.decode(inquiryURLs[i]);
        String publishURL = null;
        String regName = null;
        String registrationURL = null;
        // continue to the next registry if inquiryURL does not exist
        if (!Validator.validateURL(inquiryURL))
          continue;
        // populate and run an OpenRegistryAction
        OpenRegistryAction action = new OpenRegistryAction(controller_);
        Hashtable propertyTable = action.getPropertyTable();
        IFavoritesUDDIRegistry knownRegistry = (IFavoritesUDDIRegistry)knownRegistries.get(inquiryURL);
        boolean checkForUserDefinedCategories = false;
        File directoryFile = null;
        if (knownRegistry != null)
        {
          publishURL = knownRegistry.getPublishURL();
          regName = knownRegistry.getName();
          registrationURL = knownRegistry.getRegistrationURL();
          directoryBuffer.setLength(0);
          FavoritesUDDIRegistryFolderElement.formCategoriesDirectory(directoryBuffer,controller_.getServletEngineStateLocation(),regName);
          directoryFile = new File(directoryBuffer.toString());
          if (directoryFile.exists() && directoryFile.listFiles().length > 0)
            checkForUserDefinedCategories = true;
        }
        if (regName == null)
          regName = inquiryURL;
        if (publishURL == null && publishURLs != null && i < publishURLs.length && publishURLs[i] != null) {
          publishURL = URLUtils.decode(publishURLs[i]);
        }  
        // populate the action
        propertyTable.put(UDDIActionInputs.INQUIRY_URL, inquiryURL);
        propertyTable.put(UDDIActionInputs.REGISTRY_NAME, regName);
        if (Validator.validateURL(publishURL))
          propertyTable.put(UDDIActionInputs.PUBLISH_URL, publishURL);
        if (Validator.validateURL(registrationURL))
          propertyTable.put(UDDIActionInputs.REGISTRATION_URL, registrationURL);
          
        // Check if private registry category information is available for this registry.
        directoryBuffer.setLength(0);
        String encodedInquiryURL = URLUtils.encode(inquiryURL);
        directoryBuffer.append(controller_.getServletEngineStateLocation()).append(encodedInquiryURL).append(".properties");
        directoryFile = new File(directoryBuffer.toString());
        if (directoryFile.exists())
        {
          try
          {
            Properties p = new Properties();
            FileInputStream fin = new FileInputStream(directoryFile);
            p.load(fin);
            fin.close();
            directoryFile.delete();
            String dataDirectory = p.getProperty(UDDIActionInputs.CATEGORIES_DIRECTORY);
            if (dataDirectory != null)
              propertyTable.put(UDDIActionInputs.CATEGORIES_DIRECTORY,dataDirectory);
            checkForUserDefinedCategories = true;
          }
          catch (IOException e)
          {
            checkForUserDefinedCategories = false;
          }
        }

        if (checkForUserDefinedCategories)
          propertyTable.put(UDDIActionInputs.CHECK_USER_DEFINED_CATEGORIES,Boolean.TRUE);
        else
          propertyTable.remove(UDDIActionInputs.CHECK_USER_DEFINED_CATEGORIES);
                
        // run the action
        action.run();
        
        RegistryElement regElement = (RegistryElement)(navigatorManager_.getSelectedNode().getTreeElement());
        Enumeration userDefinedCategories = regElement.getUserDefinedCategories();
        if (userDefinedCategories != null && userDefinedCategories.hasMoreElements())
        {
          AddRegistryToUDDIPerspectiveAction action2 = new AddRegistryToUDDIPerspectiveAction(controller_);
          String categoriesDirectory = regElement.getCategoriesDirectory();
          if (categoriesDirectory != null)
            action2.linkCategoryModelsWithSavedData(userDefinedCategories,categoriesDirectory);
          else
            action2.linkCategoryModelsWithSavedData(regElement.getName(),userDefinedCategories);
        }
      }
      if (inquiryURLs.length > 0)
        controller_.setCurrentPerspective(ActionInputs.PERSPECTIVE_UDDI);
    }
  }
  
  // Preconditions: 
  // serviceNames and serviceKeys have length >= 1.
  // regNode != null
  private final void preloadServicesForRegistry(RegistryNode regNode,String[] serviceNames,String[] serviceKeys)
  {
    int regNodeId = regNode.getNodeId();
    for (int i=0;i<serviceKeys.length;i++)
    {
      navigatorManager_.setSelectedNodeId(regNodeId);
      RegFindServiceUUIDAction action = new RegFindServiceUUIDAction(controller_);
      Hashtable propertyTable = action.getPropertyTable();
      propertyTable.put(UDDIActionInputs.QUERY_NAME,serviceNames[i]);
      propertyTable.put(UDDIActionInputs.QUERY_INPUT_UUID_SERVICE_KEY,serviceKeys[i]);
      action.run();
      navigatorManager_.makeSelectedNodeVisible();
    }
  }
  
  public final void preloadServices(String[] inquiryURLs,String[] serviceNames,String[] serviceKeys)
  {
    // The algorithm will search for each service key in each inquiry URL.
    if (serviceKeys != null && serviceNames != null && serviceNames.length == serviceKeys.length)
    {
      for (int i=0;i<serviceKeys.length;i++)
      {
        if (inquiryURLs != null)
        {
          // Eliminate duplicate inquiry URLs.
          Hashtable inquiryURLsHash = new Hashtable();
          for (int j=0;j<inquiryURLs.length;j++)
            inquiryURLsHash.put(inquiryURLs[j],Boolean.TRUE);
          // Loop through all the available registries and use them if possible.
          Node uddiMainNode = navigatorManager_.getRootNode();
          Vector registryNodes = uddiMainNode.getChildNodes();
          for (int k=0;k<registryNodes.size();k++)
          {
            RegistryNode regNode = (RegistryNode)registryNodes.elementAt(k);
            RegistryElement regElement = (RegistryElement)regNode.getTreeElement();
            String existingRegistryInquiryURL = regElement.getInquiryURL();
            if (inquiryURLsHash.get(existingRegistryInquiryURL) != null)
            {
              preloadServicesForRegistry(regNode,serviceNames,serviceKeys);
              inquiryURLsHash.remove(existingRegistryInquiryURL);
            }
          }
          Enumeration inquiryURLsEnum = inquiryURLsHash.keys();
          while (inquiryURLsEnum.hasMoreElements())
          {
            String inquiryURL = (String)inquiryURLsEnum.nextElement();
            preloadUDDIRegistries(new String[] {inquiryURL},null);
            RegistryNode regNode = (RegistryNode)navigatorManager_.getSelectedNode();
            preloadServicesForRegistry(regNode,serviceNames,serviceKeys);
          }
        }
      }
    }
  }

  public final void setCategoryTModelKey(String categoryTModelKey)
  {
    categoryTModelKey_ = categoryTModelKey;
  }
  
  public final String getCategoryTModelKey()
  {
    return categoryTModelKey_;
  }
  
  private final void initCategoryBrowser(CategoryModel categoryModel,NodeManager nodeManager)
  {
    TreeElement categoryRootElement = (TreeElement)categoryModel.getRootElement();
    RootCategoryNode rootCategoryNode = new RootCategoryNode(categoryRootElement,nodeManager);
    nodeManager.setRootNode(rootCategoryNode);
    rootCategoryNode.createChildren();
  }
  
  public final NodeManager getCategoryManager()
  {
    return (NodeManager)categoryManagers_.get(categoryTModelKey_);
  }
  
  public final NodeManager getCategoryManager(CategoryModel categoryModel)
  {
    String tModelKey = categoryModel.getTModelKey();
    NodeManager categoryManager = (NodeManager)categoryManagers_.get(tModelKey);
    if (categoryManager == null)
    {
      categoryManager = new NodeManager(controller_);
      initCategoryBrowser(categoryModel,categoryManager);
      categoryManagers_.put(tModelKey,categoryManager);      
    }
    return categoryManager;
  }

  public final NodeManager getNavigatorManager()
  {
    return navigatorManager_;
  }
  
  public final NodeManager getNodeManager()
  {
    return getNavigatorManager();
  }

  public final void setWSDLType(int wsdlType)
  {
    wsdlType_ = wsdlType;
  }

  public final int getWSDLType()
  {
    return wsdlType_;
  }

  public final String getPerspectiveContentPage()
  {
    return "uddi/uddi_perspective_content.jsp";
  }

  public final int getPerspectiveId()
  {
    return ActionInputs.PERSPECTIVE_UDDI;
  }
  
  public final String getFramesetsFile()
  {
    return "uddi/scripts/uddiframesets.jsp";
  }
  
  public final String getProcessFramesetsForm()
  {
    return "uddi/forms/ProcessUDDIFramesetsForm.jsp";
  }

  public final String getPanesFile()
  {
    return "uddi/scripts/uddipanes.jsp";
  }
  
  public final String getTreeContentVar()
  {
    return "navigatorContent";
  }

  public final String getTreeContentPage()
  {
    return "uddi/navigator_content.jsp";
  }

  public final String getPropertiesContainerVar()
  {
    return "propertiesContainer";
  }

  public final String getPropertiesContainerPage()
  {
    return "uddi/properties_container.jsp";
  }

  public final String getStatusContentVar()
  {
    return "statusContent";
  }

  public final String getStatusContentPage()
  {
    return "uddi/status_content.jsp";
  }
  
  public final String getSavePerspectiveActionLink()
  {
    //return SaveUDDIPerspectiveAction.getActionLink();
    return "";
  }
  
  public final String getPerspectiveContentFramesetCols()
  {
    return perspectiveContentFramesetCols_;
  }
  
  public final void setPerspectiveContentFramesetCols(String cols)
  {
    perspectiveContentFramesetCols_ = cols;
  }
  
  public final void setSavedPerspectiveContentFramesetCols(String cols)
  {
    savedPerspectiveContentFramesetCols_ = cols;
  }
  
  public final String getSavedPerspectiveContentFramesetCols()
  {
    return savedPerspectiveContentFramesetCols_;
  }
  
  public final String getActionsContainerFramesetRows()
  {
    return actionsContainerFramesetRows_;
  }
  
  public final void setActionsContainerFramesetRows(String rows)
  {
    actionsContainerFramesetRows_ = rows;
  }
  
  public final void setSavedActionsContainerFramesetRows(String rows)
  {
    savedActionsContainerFramesetRows_ = rows;
  }
  
  public final String getSavedActionsContainerFramesetRows()
  {
    return savedActionsContainerFramesetRows_;
  }
  
  public final String getSwitchPerspectiveFormActionLink(int targetPerspectiveId,boolean forHistory)
  {
    return SwitchPerspectiveFromUDDIAction.getFormActionLink(targetPerspectiveId,forHistory);
  }
}
