/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2008
//
// Copyright in this library belongs to the University of Southampton
// University Road, Highfield, Southampton, UK, SO17 1BJ
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//  Created By:            Mark McArdle
//  Created Date:          20/05/2008
//  Created for Project:   CRISP
//
/////////////////////////////////////////////////////////////////////////
//
//  Dependencies : none
//
/////////////////////////////////////////////////////////////////////////
//
//  Last commit info:      $Author: scp $
//                         $Date: 2008-09-05 15:15:09 +0100 (Fri, 05 Sep 2008) $
//                         $Revision: 10014 $
//
/////////////////////////////////////////////////////////////////////////

package uk.ac.soton.itinnovation.grid.client.tutorial;

import org.apache.axis.message.addressing.EndpointReferenceType;
import uk.ac.soton.ecs.iam.grid.comms.client.DataConversation;
import uk.ac.soton.ecs.iam.grid.comms.client.RemoteDataService;
import uk.ac.soton.itinnovation.grid.client.membership.MembershipGroupConversation;
import uk.ac.soton.itinnovation.grid.client.membership.RemoteMembershipService;
import uk.ac.soton.itinnovation.grid.client.proxy.ProxyFactory;
import uk.ac.soton.itinnovation.grid.comms.wstrust.WSTrustUtils;
import uk.ac.soton.itinnovation.grid.types.ConversationID;
import uk.ac.soton.itinnovation.grid.types.MatchPattern;
import uk.ac.soton.itinnovation.grid.types.PolicyRule;
import uk.ac.soton.itinnovation.grid.utils.Identity;
import uk.ac.soton.itinnovation.grid.utils.IdentityProvider;
import uk.ac.soton.itinnovation.grid.utils.TestIdentityProvider;

/**
 *
 * @author mm
 */
public class MembershipTutorial {
	
	static String MEMBERSHIP_SERVICE_ENDPOINT = null;
	static String DATA_SERVICE_ENDPOINT = null;
	
	public MembershipTutorial(String membershipService,String dataService){
		MEMBERSHIP_SERVICE_ENDPOINT = membershipService;
		DATA_SERVICE_ENDPOINT = dataService;
	}

	/** Creates a new instance of JobOrchestration
	 * @param args
	 * @throws java.lang.Exception 
	 */
	public static void main(String[] args) throws Exception{
	
		/* Create a TutorialHelpers object and get a ProxyFactory
		 * object from it
		 */
		TutorialHelpers helpers = new TutorialHelpers();
		ProxyFactory proxyFactory = helpers.getFactory();

		/*Create a proxy to the membership service
		 */
		RemoteMembershipService membershipService =   
			proxyFactory.createProxy(ConversationID.getEPR(MEMBERSHIP_SERVICE_ENDPOINT),
			RemoteMembershipService.class);
		
		/* Creata a new Membership Group on the service called 'My Group'
		 */ 
		MembershipGroupConversation group = membershipService.createGroup("My Group");
		
		System.out.println(ConversationID.getURLReferenceFromEPR(group.getEndpointRef()));
		
		/* Create an identity object for Alice and use that to create a MatchPattern:
		 */ 
		IdentityProvider aliceIDP = new TestIdentityProvider("alice");
		Identity alice = aliceIDP.getIdentity();
		MatchPattern alicePattern = alice.getMatchPattern();
		
		/* Create a PolicyRule, setting the role to be member. 
		 * Members of a group can retrieve the token of a group and use it 
		 * to access other resources that they have been delegated access to:
		 */
		PolicyRule rule = new PolicyRule(alicePattern, "member");
			
		/* Add the rule to 'My Group'.  This updates the access control 
		 * policy on the group resource (at the membership service) to say 
		 * that Alice (identified by her certificate) can have the "member" role:
		 */
		group.addPolicyRule(rule);

		/* Alice is now a member of the group, but there are no resources 
		 * that can be accessed yet. We will create a data stager and
		 * delegate access
		 */
		
		System.out.println("Added Rule to '"+ConversationID.getURLReferenceFromEPR(group.getEndpointRef()));
		
		/* Create a proxy to the data service, create a data stager
		 * and upload some data
		 */ 
		EndpointReferenceType dataServiceEPR = ConversationID.getEPR(DATA_SERVICE_ENDPOINT);
		RemoteDataService dataService = proxyFactory.createProxy(dataServiceEPR, RemoteDataService.class);
		DataConversation data = dataService.createStagingArea("My Data");
		data.copyFromURL("http://www.gria.org/portal_css/Plone%20Default/logo.jpg");
		
		/* Allow 'members' of the group access to the 'reader' role on the data.
		 * This allows 'Alice' to read from the data stager
		 */ 
		data.addPolicyRule(new PolicyRule(group.getMembershipPattern(), "reader"));

		try{
			/* Now we are going to change our identity to Alice
			 * and access the data stager using the token
			 */		
			TutorialHelpers aliceHelpers = new TutorialHelpers();
			
			/*Set the identity to 'Alice'
			 */ 
			aliceHelpers.getTransport().setIdentityProvider(aliceIDP);
			
			ProxyFactory aliceProxyFactory = aliceHelpers.getFactory();
			
			/* Make a copy of the EPR of the data stager
			 */
			EndpointReferenceType aliceDataEPR = new EndpointReferenceType(data.getEndpointRef());
			
			/* We need to indicate to the Attribute Selector where 
			 * to get the token to access the data stager
			*/
			ConversationID.setTokenSource(aliceDataEPR,WSTrustUtils.createTokenSourcePolicy(group.getEndpointRef()));
		
			/* Put this EPR in the registry so the attribute
			 * selector can find it.
			 */ 
			aliceHelpers.getRegistry().registerResource(aliceDataEPR);

			/* Create a proxy to the Data Stager
			 */
			DataConversation aliceData = aliceProxyFactory.createProxy(aliceDataEPR, DataConversation.class);

			/* Read the data using the token
			 */ 
			aliceData.read();
			
		}catch(Exception e){
			throw e;
		}finally{
			/* Clean up at the services;
			 */
			group.destroy();
			data.destroy();
		}
	}
}
