/*******************************************************************************
 * 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.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);
          
          CategoryModel dWCommunityModel = new CategoryModel();
          dWCommunityModel.setServletContext(application);
          dWCommunityModel.setDefaultDataFile("/uddi/data/dWCommunity-data.txt");
          dWCommunityModel.setDisplayName(getMessage("FORM_OPTION_CATEGORY_DWCOMMUNITY"));
          dWCommunityModel.setTModelKey("UUID:8F497C50-EB05-11D6-B618-000629DC0A53");
          commonCategoryModels.put("UUID:8F497C50-EB05-11D6-B618-000629DC0A53",dWCommunityModel);
          
          application.setAttribute("commonCategoryModels",commonCategoryModels);
        }
      }
    }
    categoryTModelKey_ = null;
    
    // Starting frameset sizes.
    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);
  }
}
