/*******************************************************************************
 * 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
 * -------- -------- -----------------------------------------------------------
 * 20071024   196997 pmoogk@ca.ibm.com - Peter Moogk
 * 20080214   218996 pmoogk@ca.ibm.com - Peter Moogk, Concurrent exception fix
 * 20080625   238482 pmoogk@ca.ibm.com - Peter Moogk, Adding thread safety to the service platform api.
 *******************************************************************************/
package org.eclipse.wst.ws.service.internal.policy;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.IPolicyState;
import org.eclipse.wst.ws.service.policy.IPolicyStateEnum;
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.eclipse.wst.ws.service.policy.listeners.IPolicyChildChangeListener;
import org.eclipse.wst.ws.service.policy.listeners.IStatusChangeListener;

public class ServicePolicyImpl implements IServicePolicy
{
  private boolean                          predefined;
  private String                           id;
  private ServicePolicyImpl                parent;
  private DescriptorImpl                   descriptor;
  private List<IServicePolicy>             committedChildren;
  private List<IServicePolicy>             children;
  private PolicyStateImpl                  policyState;
  private Map<IProject, PolicyStateImpl>   projectPolicyStates;
  private List<IPolicyRelationship>        relationshipList;
  private List<IPolicyChildChangeListener> childChangeListeners;
  private ServicePolicyPlatformImpl        platform;
  private String                           enumListId;
  private String                           defaultEnumId;
  private List<IStatusChangeListener>      statusChangeListeners; 
  private IStatus                          status;
  
  private String                           unresolvedParent;
  private List<UnresolvedRelationship>     unresolvedRelationshipList;
  
  public ServicePolicyImpl( boolean isPredefined, String id, ServicePolicyPlatformImpl platform )
  {
    this.predefined                 = isPredefined;  
    this.id                         = id;
    this.children                   = new Vector<IServicePolicy>();
    this.relationshipList           = new Vector<IPolicyRelationship>();
    this.unresolvedRelationshipList = new Vector<UnresolvedRelationship>();
    this.policyState                = new PolicyStateImpl( platform.getApiPlatform(), this, null );
    this.platform                   = platform;  
    this.childChangeListeners       = new Vector<IPolicyChildChangeListener>();
    this.projectPolicyStates        = new HashMap<IProject, PolicyStateImpl>();
    this.status                     = Status.OK_STATUS;
  }
  
  public boolean isPredefined()
  {
    return predefined;
  }

  public String getId()
  {
    return id;  
  }
  
  public void setParent( ServicePolicyImpl parent )
  {
    this.parent = parent;
    
    if( parent != null )
    {
      parent.addChild( this, false );
    }
  }
  
  public void commitChanges()
  {
    policyState.commitChanges();
    
    // Make a copy of the children in the committedChildren object.
    committedChildren = new Vector<IServicePolicy>( children );
  }
  
  public void discardChanges()
  {
    policyState.discardChanges();
        
    fireChildChangesDuetoDiscard();
    
    //Restore children.
    children = new Vector<IServicePolicy>( committedChildren );
  }
  
  public List<IServicePolicy> getChildren()
  {
    return children;
  }
  
  private void addChild( ServicePolicyImpl child, boolean fireEvent )
  {
    children.add( child );
      
    if( fireEvent )
    {
      fireChildChangeEvent( child, true );
    }
  }
  
  public void removeChild(IServicePolicy policyToRemove )
  {
    if( !policyToRemove.isPredefined() )
    {
      // Remove all the children of this policy first.
      List<IServicePolicy> childPolicies = new Vector<IServicePolicy>( policyToRemove .getChildren() );
      
      for( IServicePolicy childPolicy : childPolicies )
      {
        policyToRemove.removeChild( childPolicy );
      }
      
      boolean removed = children.remove( policyToRemove  );
      
      if( removed )
      {
        platform.removePolicy( policyToRemove );
        fireChildChangeEvent( policyToRemove , false );
      }
    }
  }

  public IDescriptor getDescriptor()
  {
    if( descriptor == null )
    {
      descriptor = new DescriptorImpl();  
    }
    
    return descriptor;
  }
  
  public void setDescriptor( DescriptorImpl descriptor )
  {
    this.descriptor = descriptor;
  }

  public IServicePolicy getParentPolicy()
  {
    return parent;
  }

  public IPolicyState getPolicyState()
  {
    return policyState;
  }
  
  public IPolicyState getPolicyState( IProject project )
  {
    PolicyStateImpl projectPolicyState = projectPolicyStates.get( project );
    
    if( projectPolicyState == null )
    {
      projectPolicyState = new PolicyStateImpl( platform.getApiPlatform(), this, project );
      projectPolicyState.internalSetMutable( policyState.isMutable() );
      projectPolicyStates.put( project, projectPolicyState );
    }
    
    return projectPolicyState;
  }
  
  public IPolicyStateEnum getPolicyStateEnum()
  {
    EnumerationStateImpl newEnum = null;
    
    if( enumListId != null )
    {
      newEnum = new EnumerationStateImpl( platform.getApiPlatform(), enumListId, defaultEnumId, policyState );
    }
    
    return newEnum;
  }
  
  public IPolicyStateEnum getPolicyStateEnum( IProject project )
  {
    EnumerationStateImpl newEnum = null;
    
    if( enumListId != null )
    {
      newEnum = new EnumerationStateImpl( platform.getApiPlatform(), enumListId, defaultEnumId, getPolicyState( project ) );
    }
    
    return newEnum;
  }

  public void setPolicyState( PolicyStateImpl policyState )
  {
    this.policyState = policyState;
  }
  
  public void restoreDefaults()
  {
    // Remove all local children from the tree
    // Java will not let you remove an item from a collection
    // that is being iterated over, so we need to create a temporary
    // copy of the children collection to iterator over.
    Vector<IServicePolicy> tempChildren = new Vector<IServicePolicy>( children );
    
    for( IServicePolicy child : tempChildren )
    {
      if( !child.isPredefined() )
      {
        removeChild( child );
      }
    }
    
    policyState.restoreDefaults();
  }
  
  public void restoreDefaults( IProject project )
  {
    PolicyStateImpl stateImpl = projectPolicyStates.get( project );
    
    if( stateImpl != null )
    {
      stateImpl.restoreDefaults();
    }
  }
  
  
  public List<IPolicyRelationship> getRelationships()
  {
    return relationshipList;
  }
  
  public void setRelationships(List<IPolicyRelationship> relationships)
  {
    if( !predefined )
    {
      this.relationshipList = relationships;
    }
  }

  public String getEnumListId()
  {
    return enumListId;  
  }
  
  public void setEnumListId(String enumListId)
  {
    this.enumListId = enumListId;
  }

  public String getDefaultEnumId()
  {
    return defaultEnumId;  
  }
  
  public void setDefaultEnumId(String defaultEnumValue)
  {
    this.defaultEnumId = defaultEnumValue;
  }

  public void setUnresolvedParent( String parentId )
  {
    unresolvedParent = parentId;  
  }
    
  public void setUnresolvedRelationships( List<UnresolvedRelationship> relationships )
  {
    unresolvedRelationshipList = relationships;
  }
  
  public void resolve()
  {
    setParent( platform.getServicePolicy( unresolvedParent ) );
        
    for( UnresolvedRelationship relationship : unresolvedRelationshipList )
    {
      List<String>                       sourceEnumIdList = relationship.getSourceEnumerationList(); 
      List<UnresolvedPolicyRelationship> targetEnumIdList = relationship.getTargetEnumerationList();
      List<IStateEnumerationItem>        sourceEnumList   = getResolvedEnumList( sourceEnumIdList );
      IPolicyEnumerationList             sourcePolicyList = new PolicyEnumerationListImpl( sourceEnumList, this );
      List<IPolicyEnumerationList>       targetPolicyList = new Vector<IPolicyEnumerationList>();
      
      for( UnresolvedPolicyRelationship targetEnum : targetEnumIdList )
      {
        IServicePolicy              targetPolicy         = platform.getServicePolicy( targetEnum.getPolicyId() );
        List<IStateEnumerationItem> targetList           = getResolvedEnumList( targetEnum.getEnumList());
        IPolicyEnumerationList      targetEnumPolicyList = new PolicyEnumerationListImpl( targetList, targetPolicy );
        
        targetPolicyList.add( targetEnumPolicyList );
        
        if( targetPolicy == null )
        {
          ServicePolicyActivator.logError( "Policy id, " + targetEnum.getPolicyId() + " not found.", null );                               //$NON-NLS-1$ //$NON-NLS-2$
        }
      }
      
      IPolicyRelationship policyRelationship = new PolicyRelationshipImpl( sourcePolicyList, targetPolicyList );
      
      relationshipList.add( policyRelationship );
    }
        
    unresolvedParent = null;
    unresolvedRelationshipList = null;
  }
  
  private List<IStateEnumerationItem> getResolvedEnumList( List<String> enumIdList )
  {
    List<IStateEnumerationItem> enumList = new Vector<IStateEnumerationItem>();
    
    for( String enumId : enumIdList )
    {
      enumList.add( platform.getStateItemEnumeration( enumId ) );    
    }
    
    return enumList;
  }
  
  public void addPolicyChildChangeListener(IPolicyChildChangeListener listener)
  {
    childChangeListeners.add( listener );
  }
  
  public void removePolicyChildChangeListener(IPolicyChildChangeListener listener)
  {
    childChangeListeners.remove( listener );
  }
  
  public void addStatusChangeListener( IStatusChangeListener listener )
  {
    if( statusChangeListeners == null )
    {
      statusChangeListeners = new Vector<IStatusChangeListener>();    
    }
    
    statusChangeListeners.add( listener );
  }
  
  public void removeStatusChangeListener( IStatusChangeListener listener )
  {
    if( statusChangeListeners != null )
    {
      statusChangeListeners.remove( listener );
    }
  }
  
  public IStatus getStatus()
  {
    return status;
  }
  
  public void setStatus( IStatus status )
  {
    IStatus oldStatus = this.status;
    this.status = status;
    fireStatusChangeEvent( oldStatus, status );
  }
  
  private void fireStatusChangeEvent( IStatus oldStatus, IStatus newStatus )
  {
    if( statusChangeListeners != null )
    {
      for( IStatusChangeListener listener : statusChangeListeners )
      {
        listener.statusChange( this, oldStatus, newStatus);
      }
    }
  }
  
  private void fireChildChangesDuetoDiscard()
  {
    Set<IServicePolicy> childSet = new HashSet<IServicePolicy>( children );
    Set<IServicePolicy> committedChildSet = new HashSet<IServicePolicy>( committedChildren );
    
    for( IServicePolicy child : childSet )
    {
      if( committedChildSet.contains( child ) )
      {
        committedChildSet.remove( child );
      }
      else
      {
        // A child was added and is now being deleted by the discard.
        fireChildChangeEvent( child, false );
        platform.fireChildChangeEvent( child, false );
      }
    }
    
    // Any children left in the committed set must have been deleted and are now
    // being added back due to the discard.
    for( IServicePolicy child : committedChildSet )
    {
      fireChildChangeEvent( child, true );
      platform.fireChildChangeEvent( child, true );
    }
  }
  
  private void fireChildChangeEvent( IServicePolicy policy, boolean isAdd )
  {
    for( IPolicyChildChangeListener listener : childChangeListeners )
    {
      List<IServicePolicy> policyList = new Vector<IServicePolicy>(1);
      List<Boolean>        addedList  = new Vector<Boolean>(1);
      
      policyList.add( policy );
      addedList.add( isAdd );
      listener.childChange( policyList, addedList );     
    }
  }
}
