/*******************************************************************************
 * 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
 *******************************************************************************/
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."; //$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();
  }
}
