package org.apache.taverna.biocatalogue.model;
/*
 * 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.
 */

import java.util.HashMap;
import java.util.Map;

import javax.swing.Icon;
import javax.swing.JOptionPane;
import javax.swing.ListCellRenderer;

import org.apache.taverna.biocatalogue.model.connectivity.BeansForJSONLiteAPI;
import org.apache.taverna.biocatalogue.model.connectivity.BioCatalogueClient;
import org.apache.taverna.biocatalogue.ui.search_results.RESTMethodListCellRenderer;
import org.apache.taverna.biocatalogue.ui.search_results.SOAPOperationListCellRenderer;
import org.apache.taverna.biocatalogue.ui.search_results.ServiceListCellRenderer;
import org.apache.taverna.workbench.MainWindow;

import org.apache.log4j.Logger;
import org.biocatalogue.x2009.xml.rest.Registry;
import org.biocatalogue.x2009.xml.rest.ResourceLink;
import org.biocatalogue.x2009.xml.rest.RestMethod;
import org.biocatalogue.x2009.xml.rest.RestMethods;
import org.biocatalogue.x2009.xml.rest.Service;
import org.biocatalogue.x2009.xml.rest.ServiceProvider;
import org.biocatalogue.x2009.xml.rest.Services;
import org.biocatalogue.x2009.xml.rest.SoapOperation;
import org.biocatalogue.x2009.xml.rest.SoapOperations;
import org.biocatalogue.x2009.xml.rest.User;

/**
 * @author Sergejs Aleksejevs
 */
public class Resource
{
  /**
   * A single point of definition of the types of resources that the BioCatalogue plugin
   * "knows" about. This enum provides various details about resource types -
   * display names for single items of that type, names of collections of items of that
   * type, icons to represent the items of a particular type, etc.
   * 
   * @author Sergejs Aleksejevs
   */
  public static enum TYPE
  {
    // the order is important - all these types will appear in the user interface
    // in the same order as listed here
    @SuppressWarnings("serial")
	SOAPOperation (SoapOperation.class, SoapOperations.class, BeansForJSONLiteAPI.SOAPOperationsIndex.class, "WSDL service", "WSDL services",
                   "WSDL services can be directly imported into the current workflow or Service Panel",
                   ResourceManager.getIconFromTaverna(ResourceManager.SOAP_OPERATION_ICON), true, true, true, false, true, true, true, true,
                   SOAPOperationListCellRenderer.class, BioCatalogueClient.API_SOAP_OPERATIONS_URL,
                   new HashMap<String,String>() {{
                   }},
                   new HashMap<String,String>(BioCatalogueClient.API_INCLUDE_ANCESTORS) {{
                     put(BioCatalogueClient.API_PER_PAGE_PARAMETER, ""+BioCataloguePluginConstants.API_DEFAULT_REQUESTED_SOAP_OPERATION_COUNT_PER_PAGE);
                   }},
                   BioCataloguePluginConstants.API_DEFAULT_REQUESTED_SOAP_OPERATION_COUNT_PER_PAGE,
                   BioCatalogueClient.API_SOAP_OPERATION_FILTERS_URL),
                   
    @SuppressWarnings("serial")
	RESTMethod    (RestMethod.class, RestMethods.class, BeansForJSONLiteAPI.RESTMethodsIndex.class, "REST service", "REST services",
                   "REST services can be directly imported into the current workflow or Service Panel",
                   ResourceManager.getIconFromTaverna(ResourceManager.REST_METHOD_ICON), true, true, true, false, true, false, true, true,
                   RESTMethodListCellRenderer.class, BioCatalogueClient.API_REST_METHODS_URL,
                   new HashMap<String,String>() {{
                   }},
                   new HashMap<String,String>(BioCatalogueClient.API_INCLUDE_ANCESTORS) {{
                     put(BioCatalogueClient.API_PER_PAGE_PARAMETER, ""+BioCataloguePluginConstants.API_DEFAULT_REQUESTED_REST_METHOD_COUNT_PER_PAGE);
                   }},
                   BioCataloguePluginConstants.API_DEFAULT_REQUESTED_REST_METHOD_COUNT_PER_PAGE,
                   BioCatalogueClient.API_REST_METHOD_FILTERS_URL); //,
                   
    // TODO - the following resource types have been disabled, as no actions for them can be done yet
    //        -- they are still to be implemented; if the following types are uncommented, they will be
    //        automatically searchable and visible in BioCatalogue Exploration tab; ListCellRenderers, however,
    //        would need to be added first.
//    @SuppressWarnings("serial")
//	Service       (Service.class, Services.class, BeansForJSONLiteAPI.ServicesIndex.class, "Web service", "Web services",
//                   "<html>Web services represent collections of WSDL services or REST services.<br>" +
//                         "They cannot be directly imported into the current workflow or Service Panel,<br>" +
//                         "but they may contain much more information about individual WSDL or REST<br>" +
//                         "services and also provide some context for their usage.</html>",
//                   ResourceManager.getImageIcon(ResourceManager.SERVICE_ICON), true, true, true, false, false, false, true,
//                   ServiceListCellRenderer.class, BioCatalogueClient.API_SERVICES_URL, 
//                   new HashMap<String,String>(BioCatalogueClient.API_INCLUDE_SUMMARY) {{
//                   }},
//                   new HashMap<String,String>() {{
//                     put(BioCatalogueClient.API_PER_PAGE_PARAMETER, ""+BioCataloguePluginConstants.API_DEFAULT_REQUESTED_WEB_SERVICE_COUNT_PER_PAGE);
//                   }},
//                   BioCataloguePluginConstants.API_DEFAULT_REQUESTED_WEB_SERVICE_COUNT_PER_PAGE,
//                   BioCatalogueClient.API_SERVICE_FILTERS_URL),
//                   
//    ServiceProvider (ServiceProvider.class, ServiceProviders.class, BeansForJSONLiteAPI.ServiceProvidersIndex.class, "Service Provider", "Service Providers", "",
//                     ResourceManager.getImageIcon(ResourceManager.SERVICE_PROVIDER_ICON), false, false, false, false, false, false, false,
//                     ServiceProviderListCellRenderer.class, BioCatalogueClient.API_SERVICE_PROVIDERS_URL,
//                     new HashMap<String,String>() {{
//                     }},
//                     new HashMap<String,String>() {{
//                       put(BioCatalogueClient.API_PER_PAGE_PARAMETER, ""+BioCataloguePluginConstants.API_DEFAULT_REQUESTED_SERVICE_PROVIDER_COUNT_PER_PAGE);
//                     }},
//                     BioCataloguePluginConstants.API_DEFAULT_REQUESTED_SERVICE_PROVIDER_COUNT_PER_PAGE,
//                     null),
//                     
//    User          (User.class, Users.class, BeansForJSONLiteAPI.UsersIndex.class, "User", "Users", "",
//                   ResourceManager.getImageIcon(ResourceManager.USER_ICON), false, false, true, false, false, false, false,
//                   UserListCellRenderer.class, BioCatalogueClient.API_USERS_URL,
//                   new HashMap<String,String>() {{
//                   }},
//                   new HashMap<String,String>() {{
//                     put(BioCatalogueClient.API_PER_PAGE_PARAMETER, ""+BioCataloguePluginConstants.API_DEFAULT_REQUESTED_USER_COUNT_PER_PAGE);
//                   }},
//                   BioCataloguePluginConstants.API_DEFAULT_REQUESTED_USER_COUNT_PER_PAGE,
//                   BioCatalogueClient.API_USER_FILTERS_URL);
    
    
    @SuppressWarnings("unchecked")
	private Class xmlbeansGeneratedClass;
    @SuppressWarnings("unchecked")
	private Class xmlbeansGeneratedCollectionClass;
    private Class<?> jsonLiteAPIBindingBeanClass;
    private String resourceTypeName;
    private String resourceCollectionName;
    private String resourceTabTooltip;
    private Icon icon;
    private boolean defaultType;
    private boolean suitableForTagSearch;
    private boolean suitableForFiltering;
    private boolean suitableForOpeningInPreviewBrowser;
    private boolean suitableForAddingToServicePanel;
    private boolean suitableForAddingToWorkflowDiagram;
    private boolean suitableForHealthCheck;
    private Class<? extends ListCellRenderer> resultListingCellRendererClass;
    private String apiResourceCollectionIndex;
    private Map<String,String> apiResourceCollectionIndexSingleExpandedResourceAdditionalParameters;
    private Map<String,String> apiResourceCollectionIndexAdditionalParameters;
    private int apiResourceCountPerIndexPage;
    private String apiResourceCollectionFilters;
	private final boolean suitableForAddingAllToServicePanel;
    
    @SuppressWarnings("unchecked")
	TYPE(Class xmlbeansGeneratedClass, Class xmlbeansGeneratedCollectionClass, Class<?> jsonLiteAPIBindingBeanClass,
        String resourceTypeName, String resourceCollectionName, String resourceTabTooltip, Icon icon,
        boolean defaultType, boolean suitableForTagSearch, boolean suitableForFiltering, boolean suitableForOpeningInPreviewBrowser,
        boolean suitableForAddingToServicePanel, boolean suitableForAddingAllToServicePanel, boolean suitableForAddingToWorkflowDiagram,
        boolean suitableForHealthCheck, Class<? extends ListCellRenderer> resultListingCellRendererClass,
        String apiResourceCollectionIndex, Map<String,String> apiResourceCollectionIndexSingleExpandedResourceAdditionalParameters,
        Map<String,String> apiResourceCollectionIndexAdditionalParameters, int apiResourceCountPerIndexListingPage,
        String apiResourceCollectionFilters)
    {
      this.xmlbeansGeneratedClass = xmlbeansGeneratedClass;
      this.xmlbeansGeneratedCollectionClass = xmlbeansGeneratedCollectionClass;
      this.jsonLiteAPIBindingBeanClass = jsonLiteAPIBindingBeanClass;
      this.resourceTypeName = resourceTypeName;
      this.resourceCollectionName = resourceCollectionName;
      this.resourceTabTooltip = resourceTabTooltip;
      this.icon = icon;
      this.defaultType = defaultType;
      this.suitableForTagSearch = suitableForTagSearch;
      this.suitableForFiltering = suitableForFiltering;
      this.suitableForOpeningInPreviewBrowser = suitableForOpeningInPreviewBrowser;
      this.suitableForAddingToServicePanel = suitableForAddingToServicePanel;
	this.suitableForAddingAllToServicePanel = suitableForAddingAllToServicePanel;
      this.suitableForAddingToWorkflowDiagram = suitableForAddingToWorkflowDiagram;
      this.suitableForHealthCheck = suitableForHealthCheck;
      this.resultListingCellRendererClass = resultListingCellRendererClass;
      this.apiResourceCollectionIndex = apiResourceCollectionIndex;
      this.apiResourceCollectionIndexSingleExpandedResourceAdditionalParameters = apiResourceCollectionIndexSingleExpandedResourceAdditionalParameters;
      this.apiResourceCollectionIndexAdditionalParameters = apiResourceCollectionIndexAdditionalParameters;
      this.apiResourceCountPerIndexPage = apiResourceCountPerIndexListingPage;
      this.apiResourceCollectionFilters = apiResourceCollectionFilters;
    }
    
    
    
    @SuppressWarnings("unchecked")
	public Class getXmlBeansGeneratedClass() {
      return this.xmlbeansGeneratedClass;
    }
    
    /**
     * @return Class that represents collection of resources of this type,
     *         as represented by XmlBeans.
     */
    @SuppressWarnings("unchecked")
	public Class getXmlBeansGeneratedCollectionClass() {
      return this.xmlbeansGeneratedCollectionClass;
    }
    
    
    /**
     * @return Class of the bean to be used when de-serialising JSON
     *         data received from the 'Lite' BioCatalogue JSON API's index
     *         of resources of this type.  
     */
    public Class<?> getJsonLiteAPIBindingBeanClass() {
      return this.jsonLiteAPIBindingBeanClass;
    }
    
    
    /**
     * @return Display name of a type of a single item belonging to that type.
     *         (E.g. 'User' or 'Service') 
     */
    public String getTypeName() {
      return this.resourceTypeName;
    }
    
    /**
     * @return Display name of a collection of items of this type.
     *         (E.g. 'Users' or 'Services').
     */
    public String getCollectionName() {
      return this.resourceCollectionName;
    }
    
    /**
     * @return HTML-formatted string that can be used as a tooltip
     *         for tabs in BioCatalogue Exploration tab of BioCatalogue
     *         perspective.
     */
    public String getCollectionTabTooltip() {
      return this.resourceTabTooltip;
    }
    
    /**
     * @return Small icon that represents this resource type.
     */
    public Icon getIcon() {
      return this.icon;
    }
    
    /**
     * @return <code>true</code> - if used for search by default;<br/>
     *         <code>false</code> - otherwise.
     */
    public boolean isDefaultSearchType() {
      return this.defaultType;
    }
    
    /**
     * Resources not of all resource types can be searched for by tags (although every resource type
     * can be searched for by a free-text query).
     * 
     * @return <code>true</code> if resources of this type can be searched for by tags,<br/>
     *         <code>false</code> otherwise.
     */
    public boolean isSuitableForTagSearch() {
      return this.suitableForTagSearch;
    }
    
    /**
     * Not all resource types are suitable for filtering - for example, there are no
     * filters available for service providers in BioCatalogue.
     * 
     * @return <code>true</code> indicates that tab dedicated to displaying search
     *         results of this resource type can have a filter tree.
     */
    public boolean isSuitableForFiltering() {
      return this.suitableForFiltering;
    }
    
    /**
     * @return <code>true</code> indicates that "Preview" option can be made
     *         available for items of this type, as preview factory would be implemented
     *         for such resources.
     */
    public boolean isSuitableForOpeningInPreviewBrowser() {
      return this.suitableForOpeningInPreviewBrowser;
    }
    
    public boolean isSuitableForAddingToServicePanel() {
      return this.suitableForAddingToServicePanel;
    }
    
    public boolean isSuitableForAddingToWorkflowDiagram() {
      return this.suitableForAddingToWorkflowDiagram;
    }
    
    /**
     * @return <code>true</code> indicates that monitoring data can be obtained
     *         from BioCatalougue for this type of resource.
     */
    public boolean isSuitableForHealthCheck() {
      return this.suitableForHealthCheck;
    }
    
    
    /**
     * This method helps to defer instantiation of ListCellRenderers
     * until they are first accessed - it is because construction of
     * the renderers requires knowledge of all available resource types,
     * therefore they cannot be instantiated until after Resource class
     * has been fully loaded.
     * 
     * @return {@link ListCellRenderer} for this type of resources or
     *         <code>null</code> if an error has occurred during
     *         instantiation of required renderer.
     */
    public ListCellRenderer getResultListingCellRenderer() {
      try {
        return this.resultListingCellRendererClass.newInstance();
      }
      catch (Exception e) {
        Logger.getLogger(Resource.class).error("Unable to instantiate search results ListCellRenderer for " +
                                               this.getCollectionName(), e);
        JOptionPane.showMessageDialog(MainWindow.getMainWindow(), 
            "Taverna was unable to instantiate ListCellRenderer for " + this.getCollectionName() + ".\n\n" +
            "This may make Taverna unstable.", "Service Catalogue Plugin", JOptionPane.ERROR_MESSAGE);
        return null;
      }
    }
    
    /**
     * @return URL in the BioCatalogue API that provides an index of the collection of
     *         all resources of this type.
     */
    public String getAPIResourceCollectionIndex() {
      return apiResourceCollectionIndex;
    }
    
    /**
     * @return Keys and values for any additional URL parameters that need to be included into the
     *         BioCatalogue API requests that are made in order to fetch all necessary additional
     *         details for a *single* expanded entry in the search results listing. 
     */
    public Map<String,String> getResourceCollectionIndexSingleExpandedResourceAdditionalParameters() {
      return apiResourceCollectionIndexSingleExpandedResourceAdditionalParameters;
    }
    
    /**
     * @return Keys and values for any additional URL parameters that need to be included into the
     *         requests sent to filtered indexes of collections of this type in the BioCatalogue API.
     */
    public Map<String,String> getAPIResourceCollectionIndexAdditionalParameters() {
      return apiResourceCollectionIndexAdditionalParameters;
    }
    
    /**
     * @return Number of resources of this type that one page of search results from
     *         the API will contain.
     */
    public int getApiResourceCountPerIndexPage() {
      return apiResourceCountPerIndexPage;
    }
    
    /**
     * @return BioCatalogue API URL that provides a collection of filters for the
     *         resource of this type. 
     */
    public String getAPIResourceCollectionFiltersURL() {
      return apiResourceCollectionFilters;
    }
    
    
    /**
     * This method is useful for adding / removing tabs into the results view - provides
     * and index for the tabbed view to place a tab, relevant to a particular resource type.
     * This helps to preserve the order of tabs after adding / removing them.
     * 
     * @return Zero-based index of this resource type in the <code>RESOURCE_TYPE</code> enum or 
     *         <code>-1</code> if not found (which is impossible under normal conditions).
     */
    public int index()
    {
      TYPE[] values = TYPE.values();
      for (int i = 0; i < values.length; i++) {
        if (this == values[i]) {
          return (i);
        }
      }
      return (-1);
    }



	/**
	 * @return the suitableForAddingAllToServicePanel
	 */
	public boolean isSuitableForAddingAllToServicePanel() {
		return suitableForAddingAllToServicePanel;
	}
    
  };
  
  
  
  // ----------------------------- RESOURCE CLASS -------------------------------
  
  
  // current resource data
  private final TYPE resourceType;
  private final String resourceURL;
  private final String resourceTitle;
  
  
  public Resource(String resourceURL, String resourceTitle)
  {
    this.resourceURL = extractPureResourceURLFromPreviewActionCommand(resourceURL);
    this.resourceTitle = resourceTitle;
    this.resourceType = getResourceTypeFromResourceURL(resourceURL);
  }
  
  public TYPE getType() {
    return resourceType;
  }
  
  public String getURL() {
    return resourceURL;
  }

  public String getTitle() {
    return resourceTitle;
  }
  
  
  
  public boolean equals(Object other)
  {
    if (other instanceof Resource)
    {
      // compare by all components
      Resource otherRes = (Resource)other;
      return (this.resourceType == otherRes.resourceType &&
              this.resourceTitle.equals(otherRes.resourceTitle) &&
              this.resourceURL.equals(otherRes.resourceURL));
    }
    else {
      // other object is of different type
      return (false);
    }
  }
  
  
  /**
   * @param url Either URL of the resource in BioCatalogue or preview action command
   *            ({@link BioCataloguePluginConstants#ACTION_PREVIEW_RESOURCE}).
   * @return Type of this resource according to the BioCatalogue URL that points to this
   *         resource or <code>null</code> if the type of the resource couldn't be determined.
   */
  public static TYPE getResourceTypeFromResourceURL(String url)
  {
    String pureURL = extractPureResourceURLFromPreviewActionCommand(url);
    
//    if (pureURL.startsWith(BioCatalogueClient.API_SERVICES_URL))               return(TYPE.Service);
//    else
    if (pureURL.startsWith(BioCatalogueClient.API_SOAP_OPERATIONS_URL)) {
    	return(TYPE.SOAPOperation);
    }
    if (pureURL.startsWith(BioCatalogueClient.API_REST_METHODS_URL)) {
    	return(TYPE.RESTMethod);
    }
//    else if (pureURL.startsWith(BioCatalogueClient.API_SERVICE_PROVIDERS_URL)) return(TYPE.ServiceProvider);   // TODO - re-enable these lines as soon as ServiceProvider and User type are started to be used
//    else if (pureURL.startsWith(BioCatalogueClient.API_USERS_URL))             return(TYPE.User);
      return (null);
  }
  
  
  /**
   * @param previewActionCommand Either resource preview action command or a 'pure' resource URL already.
   * @return A "pure" resource URL in BioCatalogue with the action prefix
   *         ({@link BioCataloguePluginConstants#ACTION_PREVIEW_RESOURCE}) removed. 
   */
  public static String extractPureResourceURLFromPreviewActionCommand(String previewActionCommand)
  {
    return (previewActionCommand.startsWith(BioCataloguePluginConstants.ACTION_PREVIEW_RESOURCE) ?
            previewActionCommand.substring(BioCataloguePluginConstants.ACTION_PREVIEW_RESOURCE.length()) :
            previewActionCommand);
  }
  
  
  /**
   * @param resource
   * @return Display name for listings of items.
   */
  public static String getDisplayNameForResource(ResourceLink resource)
  {
    if (resource instanceof SoapOperation) {
      return ((SoapOperation)resource).getName();
    }
    else if (resource instanceof RestMethod)
    {
      RestMethod restMethod = (RestMethod)resource;
      return (restMethod.getName() == null || restMethod.getName().length() == 0 ?
              restMethod.getEndpointLabel() :
              restMethod.getName());
    }
    else if (resource instanceof Service) {
      return ((Service)resource).getName();
    }
    else if (resource instanceof ServiceProvider) {
      return ((ServiceProvider)resource).getName();
    }
    else if (resource instanceof User) {
      return ((User)resource).getName();
    }
    else if (resource instanceof Registry) {
      return ((Registry)resource).getName();
    }
    else if (resource instanceof LoadingResource) {
      return (resource.getResourceName());
    }
    else {
      return ("ERROR: ITEM NOT RECOGNISED - Item is of known generic type from the Service Catalogue Plugin, but not specifically recognised" + resource.toString());
    }
  }
  
}
