/*******************************************************************************
 * Copyright (c) 2007, 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
 * -------- -------- -----------------------------------------------------------
 * 20071030   196997 pmoogk@ca.ibm.com - Peter Moogk
 * 20080325   222095 pmoogk@ca.ibm.com - Peter Moogk
 * 20080626   238635 pmoogk@ca.ibm.com - Peter Moogk, Locally added service policy nodes meta data coliding with state data.
 *******************************************************************************/
package org.eclipse.wst.ws.service.internal.policy;

import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.wst.ws.service.policy.IDescriptor;
import org.eclipse.wst.ws.service.policy.IPolicyEnumerationList;
import org.eclipse.wst.ws.service.policy.IPolicyRelationship;
import org.eclipse.wst.ws.service.policy.IServicePolicy;
import org.eclipse.wst.ws.service.policy.IStateEnumerationItem;
import org.eclipse.wst.ws.service.policy.PolicyEnumerationListImpl;
import org.eclipse.wst.ws.service.policy.PolicyRelationshipImpl;
import org.eclipse.wst.ws.service.policy.ServicePolicyActivator;
import org.osgi.service.prefs.BackingStoreException;

public class LocalUtils
{
  private static final String BASE_KEY      = "org.eclipse.wst.local."; //$NON-NLS-1$
  private static final String LOCAL_IDS_KEY = "localIds"; //$NON-NLS-1$
  private static final String PARENT_KEY    = "parentId"; //$NON-NLS-1$
  private static final String MUTABLE_KEY   = "mutable"; //$NON-NLS-1$
  private static final String DESCR_KEY     = "description"; //$NON-NLS-1$
  private static final String LONGNAME_KEY  = "longname"; //$NON-NLS-1$
  private static final String SHORTNAME_KEY = "shortname"; //$NON-NLS-1$
  private static final String ICONPATH_KEY  = "iconpath"; //$NON-NLS-1$
  private static final String ICONBUND_KEY  = "iconbundleid"; //$NON-NLS-1$
  private static final String HELPID_KEY    = "contexthelpid"; //$NON-NLS-1$
  private static final String ENUMLIST_KEY  = "enumlistid"; //$NON-NLS-1$
  private static final String DEFENUM_KEY   = "defaultenumid"; //$NON-NLS-1$
  private static final String REL_KEY       = "rel"; //$NON-NLS-1$
  private static final String TARGET_SUFFIX = ".target"; //$NON-NLS-1$
  private static final String SOURCE_SUFFIX = ".source"; //$NON-NLS-1$
  
  public static List<String> getLocalPolicyIds()
  {
    List<String>        result      = new Vector<String>();
    IEclipsePreferences preferences = getPreferences();
    String              key         = BASE_KEY + LOCAL_IDS_KEY;
    String              idsValue    = preferences.get( key , "" ); //$NON-NLS-1$
    
    if( !idsValue.equals( "" ) ) //$NON-NLS-1$
    {
      result = createStringList( idsValue );
    }
    
    return result;
  }
  
  public static void saveLocalIds( List<String> localIds )
  { 
    IEclipsePreferences preferences = getPreferences();
    String              key         = BASE_KEY + LOCAL_IDS_KEY;
    
    if( localIds.size() > 0 )
    {
      preferences.put( key, createSpaceDelimitedString( localIds ) );
    }
  }
  
  public static void removeAllPreferencePolicies( String startsWith, IEclipsePreferences prefs )
  {
    if( startsWith == null ) startsWith = BASE_KEY;
    
    try
    {
      IEclipsePreferences preferences = prefs == null ? getPreferences() : prefs;
      String[]            keys        = preferences.keys();
      
      for( String key : keys )
      {
        if( key.startsWith( startsWith ) )
        {
          preferences.remove( key );
        }
      }
    }
    catch( BackingStoreException exc )
    {
      ServicePolicyActivator.logError( "Error loading service policy local preferences.", exc); //$NON-NLS-1$
    }
  }
  
  public static void saveLocalPolicy( ServicePolicyImpl policy )
  {
    IEclipsePreferences preferences = getPreferences();
    String              policyId    = policy.getId();
    IDescriptor         descriptor  = policy.getDescriptor();
    IServicePolicy      parent      = policy.getParentPolicy();
    
    save( preferences, policyId, PARENT_KEY,  parent == null ? null : parent.getId() );
    save( preferences, policyId, MUTABLE_KEY, "" + policy.getPolicyState().isMutable() ); //$NON-NLS-1$
    save( preferences, policyId, ENUMLIST_KEY, policy.getEnumListId() );
    save( preferences, policyId, DEFENUM_KEY, policy.getDefaultEnumId() );
    save( preferences, policyId, DESCR_KEY, descriptor.getDescription() );
    save( preferences, policyId, SHORTNAME_KEY, descriptor.getShortName() );
    save( preferences, policyId, LONGNAME_KEY, descriptor.getLongName() );
    save( preferences, policyId, ICONPATH_KEY, descriptor.getIconPath() );
    save( preferences, policyId, ICONBUND_KEY, descriptor.getIconBundleId() );
    save( preferences, policyId, HELPID_KEY, descriptor.getContextHelpId() );
    saveRelationships( preferences, policyId, policy.getRelationships() );
  }
  
  public static void loadLocalPolicy( String policyId, ServicePolicyPlatformImpl platform )
  {
    IEclipsePreferences preferences = getPreferences();
    ServicePolicyImpl   policy      = platform.getServicePolicy( policyId );
    DescriptorImpl      descriptor  = (DescriptorImpl)policy.getDescriptor();
    String              parentId    = preferences.get( createKey( policyId, PARENT_KEY), null );
    
    if( parentId != null )
    {
      IServicePolicy parentPolicy = platform.getServicePolicy( parentId );
      
      policy.setParent( (ServicePolicyImpl)parentPolicy );
    }
    
    policy.getPolicyState().setMutable( preferences.getBoolean( createKey( policyId, MUTABLE_KEY), true ) );
    policy.setEnumListId( preferences.get( createKey( policyId, ENUMLIST_KEY), null ) );
    policy.setDefaultEnumId( preferences.get( createKey( policyId, DEFENUM_KEY), null ) );
    descriptor.setDescription( preferences.get( createKey( policyId, DESCR_KEY), null ) );
    descriptor.setShortName( preferences.get( createKey( policyId, SHORTNAME_KEY), null ) );
    descriptor.setLongName( preferences.get( createKey( policyId, LONGNAME_KEY), null ) );
    descriptor.setIconPath( preferences.get( createKey( policyId, ICONPATH_KEY), null ) );
    descriptor.setIconBundleId( preferences.get( createKey( policyId, ICONBUND_KEY), null ) );
    descriptor.setContextHelpId( preferences.get( createKey( policyId, HELPID_KEY), null ) );
    policy.setRelationships( loadRelationships( preferences, policyId, platform ) );
  }
  
  private static IEclipsePreferences getPreferences()
  {
    return new InstanceScope().getNode( ServicePolicyActivator.PLUGIN_ID );    
  }
  
  private static List<String> createStringList( String spaceDelimitedString )
  {
    String[] splitValues = spaceDelimitedString.split( " " ); //$NON-NLS-1$
    
    return Arrays.asList( splitValues );
  }
  
  private static String createSpaceDelimitedString( List<String> stringList )
  {
    StringBuffer buffer = new StringBuffer();
    
    for( int index = 0; index < stringList.size(); index++ )
    {
      String id = stringList.get( index );
      
      buffer.append( id );
      
      if( index < (stringList.size() - 1) ) buffer.append( ' ' );
    }

    return buffer.toString();
  }
  
  private static void saveRelationships( IEclipsePreferences preferences, String policyId, List<IPolicyRelationship> relationships )
  {
    for( int index = 0; index < relationships.size(); index++ )
    {
      IPolicyRelationship          relationship   = relationships.get( index );
      IPolicyEnumerationList       policyList     = relationship.getPolicyEnumerationList();
      List<IPolicyEnumerationList> targetPolicies = relationship.getRelatedPolicies();
      
      savePolicyRelationship( index+1, preferences, policyId, policyList, SOURCE_SUFFIX );
      
      for( int targetIndex = 0; targetIndex < targetPolicies.size(); targetIndex++ )
      {
        IPolicyEnumerationList targetPolicy = targetPolicies.get( targetIndex );
        String                 targetSuffix = TARGET_SUFFIX + (targetIndex+1);
        
        savePolicyRelationship( index+1, preferences, policyId, targetPolicy, targetSuffix );
      }
    }
  }
  
  private static List<IPolicyRelationship> loadRelationships( IEclipsePreferences preferences, String policyId, ServicePolicyPlatformImpl platform )
  {
    List<IPolicyRelationship> relationships = new Vector<IPolicyRelationship>();
    int                       relCount      = 1;
    IPolicyEnumerationList    sourceList    = loadPolicyRelationship( relCount, preferences, platform, policyId, SOURCE_SUFFIX );
    
    while( sourceList != null )
    {
      int                          targetCount  = 1;
      String                       targetSuffix = TARGET_SUFFIX + targetCount;
      IPolicyEnumerationList       targetList   = loadPolicyRelationship( relCount, preferences, platform, policyId, targetSuffix );
      List<IPolicyEnumerationList> targets      = new Vector<IPolicyEnumerationList>();
      
      while( targetList != null )
      {
        targets.add( targetList );
        targetCount++;
        targetSuffix = TARGET_SUFFIX + targetCount;
        targetList = loadPolicyRelationship( relCount, preferences, platform, policyId, targetSuffix );
      }
      
      relationships.add( new PolicyRelationshipImpl( sourceList, targets ) );
      relCount++;
      sourceList = loadPolicyRelationship( relCount, preferences, platform, policyId, SOURCE_SUFFIX );
    }
    
    return relationships;
  }
  
  private static void savePolicyRelationship( int                    relCount, 
                                              IEclipsePreferences    preferences, 
                                              String                 policyId,
                                              IPolicyEnumerationList enumList,
                                              String                 keySuffix )
  {
    String key   = createKey( policyId, REL_KEY + relCount + keySuffix );
    String value = createRelationshipValue( enumList );
    
    preferences.put( key, value );
  }
  
  private static IPolicyEnumerationList loadPolicyRelationship( int                       relCount,
                                                                IEclipsePreferences       preferences,
                                                                ServicePolicyPlatformImpl platform,
                                                                String                    policyId,
                                                                String                    keySuffix )
  {
    String                 key      = createKey( policyId, REL_KEY + relCount + keySuffix );
    String                 value    = preferences.get( key, "" ); //$NON-NLS-1$
    IPolicyEnumerationList enumList = null;
    
    if( !value.equals( "" ) ) //$NON-NLS-1$
    {
      String[]                    splitValue     = value.split( " " ); //$NON-NLS-1$
      String                      targetPolicyId = splitValue[0];
      IServicePolicy              targetPolicy   = platform.getServicePolicy( targetPolicyId );
      List<IStateEnumerationItem> items          = new Vector<IStateEnumerationItem>();
      
      for( int index = 1; index < splitValue.length; index++ )
      {
        IStateEnumerationItem item = platform.getStateItemEnumeration( splitValue[index] );
        
        items.add( item );
      }
      
      enumList = new PolicyEnumerationListImpl( items, targetPolicy );
    }
    
    return enumList;
  }
  
  /**
   * This method will create a space delimited string of enumerations id.
   * The first id in the list will be the policy id for this relationship.
   * Subsequent ids will be enumeration item ids.
   * 
   * @param enumList
   * @return
   */
  private static String createRelationshipValue( IPolicyEnumerationList enumList )
  {
    List<String>                stringList = new Vector<String>();
    List<IStateEnumerationItem> itemList   = enumList.getEnumerationList();
    
    stringList.add( enumList.getPolicy().getId() );
    
    for( IStateEnumerationItem item : itemList )
    {
      stringList.add( item.getId() );  
    }
    
    return createSpaceDelimitedString( stringList );
  }
  
  private static void save( IEclipsePreferences preferences, String policyId, String key, String value )
  {
    if( value != null && !value.equals( "" ) ) //$NON-NLS-1$
    {
      preferences.put( createKey(policyId,key), value );      
    }
  }
  
  private static String createKey( String id, String key )
  {
    StringBuffer buffer = new StringBuffer(50);
    
    buffer.append( BASE_KEY );
    buffer.append( id );
    buffer.append( '.' );
    buffer.append( key );
    
    return buffer.toString();
  }
}
