/*
 * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationAdminPermission.java,v 1.31 2005/12/20 11:23:39 ckarai Exp $
 * 
 * Copyright (c) OSGi Alliance (2004, 2005). 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.
 */

package org.osgi.service.application;

import java.security.Permission;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;

import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;

/**
 * This class implements permissions for manipulating applications and
 * their instances.
 * <P>
 * ApplicationAdminPermission can be targeted to applications that matches the
 * specified filter.
 * <P>
 * ApplicationAdminPermission may be granted for different actions:
 * <code>lifecycle</code>, <code>schedule</code> and <code>lock</code>.
 * The permission <code>schedule</code> implies the permission
 * <code>lifecycle</code>.
 */
public class ApplicationAdminPermission extends Permission {
	private static final long serialVersionUID = 1L;
  
	/**
	 * Allows the lifecycle management of the target applications.
	 */
	public static final String LIFECYCLE_ACTION = "lifecycle";

	/**
	 * Allows scheduling of the target applications. The permission to
	 * schedule an application implies that the scheduler can also 
	 * manage the lifecycle of that application i.e. <code>schedule</code>
	 * implies <code>lifecycle</code>
	 */
	public static final String SCHEDULE_ACTION = "schedule";

	/**
	 * Allows setting/unsetting the locking state of the target applications.
	 */
	public static final String LOCK_ACTION = "lock";

	private ApplicationDescriptor	applicationDescriptor;

	/**
	 * Constructs an ApplicationAdminPermission. The <code>filter</code>
	 * specifies the target application. The <code>filter</code> is an
	 * LDAP-style filter, the recognized properties are <code>signer</code>
	 * and <code>pid</code>. The pattern specified in the <code>signer</code>
	 * is matched with the Distinguished Name chain used to sign the application. 
	 * Wildcards in a DN are not matched according to the filter string rules, 
	 * but according to the rules defined for a DN chain. The attribute 
	 * <code>pid</code> is matched with the PID of the application according to
	 * the filter string rules. 
	 * <p>
	 * If the <code>filter</code> is <code>null</code> then it matches 
	 * <code>"*"</code>. If
	 * <code>actions</code> is <code>"*"</code> then it identifies all the
	 * possible actions.
	 * 
	 * @param filter
	 *            filter to identify application. The value <code>null</code>
	 *            is equivalent to <code>"*"</code> and it indicates "all application".
	 * @param actions
	 *            comma-separated list of the desired actions granted on the
	 *            applications or "*" means all the actions. It must not be
	 *            <code>null</code>. The order of the actions in the list is
	 *            not significant.
	 * @throws InvalidSyntaxException 
	 *            is thrown if the specified <code>filter</code> is not syntactically
	 *            correct.
	 * 
	 * @exception NullPointerException
	 *                is thrown if the actions parameter is <code>null</code>
	 * 
	 * @see ApplicationDescriptor
	 * @see org.osgi.framework.AdminPermission
	 */
	public ApplicationAdminPermission(String filter, String actions) throws InvalidSyntaxException {
		super(filter == null ? "*" : filter);
		
		if( filter == null )
			filter = "*";
		
		if( actions == null )
			throw new NullPointerException( "Action string cannot be null!" );
		
		this.applicationDescriptor = null;
		this.filter = (filter == null ? "*" : filter);
		this.actions = actions;

		if( !filter.equals( "*" ) && !filter.equals( "<<SELF>>" ) )
			FrameworkUtil.createFilter( this.filter ); // check if the filter is valid
		init();
	}
	
	/**
	 * This contructor should be used when creating <code>ApplicationAdminPermission</code>
	 * instance for <code>checkPermission</code> call. 
	 * @param application the tareget of the operation, it must not be <code>null</code>
	 * @param actions the required operation. it must not be <code>null</code>
	 * @throws NullPointerException if any of the arguments is null. 
	 */
	public ApplicationAdminPermission(ApplicationDescriptor application, String actions) {
		super(application.getApplicationId());
				
		if( application == null || actions == null )
			throw new NullPointerException( "ApplicationDescriptor and action string cannot be null!" );
		
		this.filter = application.getApplicationId();
		this.applicationDescriptor = application;
		this.actions = actions;
		
		init();
	}
	
	/**
	 * This method can be used in the {@link java.security.ProtectionDomain}
	 * implementation in the <code>implies</code> method to insert the
	 * application ID of the current application into the permission being
	 * checked. This enables the evaluation of the 
	 * <code>&lt;&lt;SELF&gt;&gt;</code> pseudo targets.
	 * @param applicationId the ID of the current application.
	 * @return the permission updated with the ID of the current application
	 */
	public ApplicationAdminPermission setCurrentApplicationId(String applicationId) {
		ApplicationAdminPermission newPerm = null;
		
		if( this.applicationDescriptor == null ) {
			try {
				newPerm = new ApplicationAdminPermission( this.filter, this.actions );
			}catch( InvalidSyntaxException e ) {
				throw new RuntimeException( "Internal error" ); /* this can never happen */
			}
		}
		else	
		    newPerm = new ApplicationAdminPermission( this.applicationDescriptor, this.actions );
		
		newPerm.applicationID = applicationId;
		
		return newPerm;
	}

	/**
	 * Checks if the specified <code>permission</code> is implied by this permission.
	 * The method returns true under the following conditions:
	 * <UL>
	 * <LI> This permission was created by specifying a filter (see {@link #ApplicationAdminPermission(String, String)})
	 * <LI> The implied <code>otherPermission</code> was created for a particular {@link ApplicationDescriptor}
	 *      (see {@link #ApplicationAdminPermission(ApplicationDescriptor, String)})
	 * <LI> The <code>filter</code> of this permission mathes the <code>ApplicationDescriptor</code> specified
	 *      in the <code>otherPermission</code>. If the filter in this permission is the 
	 *      <code>&lt;&lt;SELF&gt;&gt;</code> pseudo target, then the currentApplicationId set in the 
	 *      <code>otherPermission</code> is compared to the application Id of the target 
	 *      <code>ApplicationDescriptor</code>.
	 * <LI> The list of permitted actions in this permission contains all actions required in the 
	 *      <code>otherPermission</code>  
	 * </UL> 
	 * Otherwise the method returns false.
	 * @param otherPermission the implied permission
	 * @return true if this permission implies the <code>otherPermission</code>, false otherwise.
	 */
  public boolean implies(Permission otherPermission) {
  	  if( otherPermission == null )
  	  	return false;
  	  	
      if(!(otherPermission instanceof ApplicationAdminPermission))
          return false;

      ApplicationAdminPermission other = (ApplicationAdminPermission) otherPermission;

      if( !filter.equals("*") ) {
       	if( other.applicationDescriptor == null )
       		return false;
       	
      	if( filter.equals( "<<SELF>>") ) {
            if( other.applicationID == null )
          		return false; /* it cannot be, this might be a bug */
            
      		if( !other.applicationID.equals( other.applicationDescriptor.getApplicationId() ) )
      			return false;
      	}
      	else {
      		Hashtable props = new Hashtable();
      		props.put( "pid", other.applicationDescriptor.getApplicationId() );
      		props.put( "signer", new SignerWrapper( other.applicationDescriptor ) );
      		      		
      		Filter flt = getFilter();
      		if( flt == null )
      			return false;
      		
      		if( !flt.match( props ) )
      			return false;
      	}
      }
      
      if( !actionsVector.containsAll( other.actionsVector ) )
      	return false;
      
      return true;
  }

  public boolean equals(Object with) {
  	if( with == null || !(with instanceof ApplicationAdminPermission) )
  		return false;
  	
  	ApplicationAdminPermission other = (ApplicationAdminPermission)with;  	
  	
  	// Compare actions:
  	if( other.actionsVector.size() != actionsVector.size() )
  		return false;
  	
  	for( int i=0; i != actionsVector.size(); i++ )
  		if( !other.actionsVector.contains( actionsVector.get( i ) ) )
  			return false;
  	
  	
  	return equal(this.filter, other.filter ) && equal(this.applicationDescriptor, other.applicationDescriptor)
  			&& equal(this.applicationID, other.applicationID);
  }
  
  /**
   * Compares parameters for equality. If both object are null, they are considered
   * equal.
   * @param a object to compare
   * @param b other object to compare
   * @return true if both objects are equal or both are null
   */
  private static boolean equal(Object a, Object b) {
	  // This equation is true if both references are null or both point
	  // to the same object. In both cases they are considered as equal.
	  if( a == b ) {
		  return true;
	  }
	  
	  return a.equals(b);
  }

  public int hashCode() {
	  int hc = 0;
	  for( int i=0; i != actionsVector.size(); i++ )
		  hc ^= ((String)actionsVector.get( i )).hashCode();
	  hc ^= (null == this.filter )? 0 : this.filter.hashCode();
	  hc ^= (null == this.applicationDescriptor) ? 0 : this.applicationDescriptor.hashCode();
	  hc ^= (null == this.applicationID) ? 0 : this.applicationID.hashCode();
	  return hc;
  }

  /**
   * Returns the actions of this permission.
   * @return the actions specified when this permission was created
   */
  public String getActions() {
  	return actions;
  }

  private String applicationID;

  private static final Vector ACTIONS = new Vector();
  private              Vector actionsVector;
  private final        String filter;
  private final        String actions;
  private              Filter appliedFilter = null; 
  
  static {
      ACTIONS.add(LIFECYCLE_ACTION);
      ACTIONS.add(SCHEDULE_ACTION);
      ACTIONS.add(LOCK_ACTION);
  }

  private static Vector actionsVector(String actions) {
      Vector v = new Vector();
      StringTokenizer t = new StringTokenizer(actions.toUpperCase(), ",");
      while (t.hasMoreTokens()) {
          String action = t.nextToken().trim();
          v.add(action.toLowerCase());
      }
      
      if( v.contains( SCHEDULE_ACTION ) && !v.contains( LIFECYCLE_ACTION ) )
    	  v.add( LIFECYCLE_ACTION );
      
      return v;
  }
  

  private static class SignerWrapper extends Object {
  	private String pattern;
  	private ApplicationDescriptor appDesc;
  	
  	public SignerWrapper(String pattern) {
  		this.pattern = pattern;    			
  	}
  	
  	SignerWrapper(ApplicationDescriptor appDesc) {
  		this.appDesc = appDesc;
  	}
  	
  	public boolean equals(Object o) {
  		if (!(o instanceof SignerWrapper))
  			return false;
  		SignerWrapper other = (SignerWrapper) o;
  		ApplicationDescriptor matchAppDesc = (ApplicationDescriptor) (appDesc != null ? appDesc : other.appDesc);
  		String matchPattern = appDesc != null ? other.pattern : pattern;
  		return matchAppDesc.matchDNChain(matchPattern);
  	}
  }
  
  private void init() {
		actionsVector = actionsVector( actions );

		if ( actions.equals("*") )
			actionsVector = actionsVector( LIFECYCLE_ACTION + "," + SCHEDULE_ACTION + "," + LOCK_ACTION );
		else if (!ACTIONS.containsAll(actionsVector))
      throw new IllegalArgumentException("Illegal action!");
		
		applicationID = null;
  }
  
  private Filter getFilter() {
  	String transformedFilter = filter;
  	
  	if (appliedFilter == null) {
  		try {
  			int pos = filter.indexOf("signer"); //$NON-NLS-1$
  			if (pos != -1){ 
  			
  				//there may be a signer attribute 
    			StringBuffer filterBuf = new StringBuffer(filter);
    			int numAsteriskFound = 0; //use as offset to replace in buffer
    			
    			int walkbackPos; //temp pos

    			//find occurences of (signer= and escape out *'s
    			while (pos != -1) {

    				//walk back and look for '(' to see if this is an attr
    				walkbackPos = pos-1; 
    				
    				//consume whitespace
    				while(walkbackPos >= 0 && Character.isWhitespace(filter.charAt(walkbackPos))) {
    					walkbackPos--;
    				}
    				if (walkbackPos <0) {
    					//filter is invalid - FilterImpl will throw error
    					break;
    				}
    				
    				//check to see if we have unescaped '('
    				if (filter.charAt(walkbackPos) != '(' || (walkbackPos > 0 && filter.charAt(walkbackPos-1) == '\\')) {
    					//'(' was escaped or not there
    					pos = filter.indexOf("signer",pos+6); //$NON-NLS-1$
    					continue;
    				}     				
    				pos+=6; //skip over 'signer'

    				//found signer - consume whitespace before '='
    				while (Character.isWhitespace(filter.charAt(pos))) {
    					pos++;
    				}

    				//look for '='
    				if (filter.charAt(pos) != '=') {
    					//attr was signerx - keep looking
    					pos = filter.indexOf("signer",pos); //$NON-NLS-1$
    					continue;
    				}
    				pos++; //skip over '='
    				
    				//found signer value - escape '*'s
    				while (!(filter.charAt(pos) == ')' && filter.charAt(pos-1) != '\\')) {
    					if (filter.charAt(pos) == '*') {
    						filterBuf.insert(pos+numAsteriskFound,'\\');
    						numAsteriskFound++;
    					}
    					pos++;
    				}

    				//end of signer value - look for more?
    				pos = filter.indexOf("signer",pos); //$NON-NLS-1$
    			} //end while (pos != -1)
    			transformedFilter = filterBuf.toString();
  			} //end if (pos != -1)

  			appliedFilter = FrameworkUtil.createFilter( transformedFilter );
		} catch (InvalidSyntaxException e) {
			//we will return null
		}
  	}     		
  	return appliedFilter;
  }
}
