package de.dass_it.vanhelsing.gui;

import java.util.ArrayList;
import java.util.Iterator;

import de.dass_it.www.vanhelsing.*;
//import de.dass_it.www.vanhelsing.VanHelsingCallbackHandler.*;
import de.dass_it.www.vanhelsing.VanHelsingStub.*;

/**
 * Client wraps access methods and data structure of the axis client
 * @author tgoecke
 */
public class Client {
	/**
	 * Access method to get a list of resources of a given director and resource type.
	 * @param director	the director on which the configuration is based on. 
	 * @param resource	the name of the resource, e.g. client or job
	 * @return an array of ResourceInfo objects. ResourceInfo has four attributes: <br/>
	 * 			director, resource id, resource name and resource type.
	 * 			If an Exception is thrown an empty array is returned.
	 */
	public ResourceInfo[] getListResources(String director, String resource){
		ListResourcesType lrt = new ListResourcesType();
		lrt.setDirector(director);
		lrt.setResourceType(resource);
		return getListResources(lrt);
	}
	/**
	 * Access method to get a list of resources of a given director and resource type.
	 * The argument is wrapped within the ListReosurceType object.
	 * @param lrt	ListResourceType contains the director and the resource type as strings
	 * @return 	an array of ResourceInfo objects. ResourceInfo has four attributes:
	 * 			director, resource id, resource name and resource type.
	 * 			If an Exception is thrown an empty array is returned. 
	 */
	public ResourceInfo[] getListResources(ListResourcesType lrt){
		VanHelsingStub stub;
		try {
									 
			stub = getStub();
			
			VanHelsingStub.ListResources req = new VanHelsingStub.ListResources();
			req.setListResources(lrt);
			
			VanHelsingStub.ListResourcesResponse res = stub.listResources(req);
			return (res.getListResourcesResponse()).getResource();
			
		} catch (Exception e){
			System.err.println("getListResources: " + e.toString());
		}
		return new ResourceInfo[0];
	}
	/**
	 * retrieve an array of key value pairs describing a given simple resource
	 * @param director	the director on which the configuration is based on.
	 * @param resId		the id of the resource.
	 * @return	a SimpleResource object containing a ResourceInfo object and a <br/>
	 * 			ResourceAttributeType object array.
	 */
	public SimpleResource getSimpleResource(String director, int resId){
		GetResourceType grt = new GetResourceType();
		grt.setDirector(director);
		grt.setResId(resId);
		return getSimpleResource(grt);
	}
	/**
	 * retrieve an array of key value pairs describing a given simple resource
	 * @param grt	GetResourceType contains a director and a resId.
	 * @return	a SimpleResource object containing a ResourceInfo object and a <br/>
	 * 			ResourceAttributeType object array.
	 */
	public SimpleResource getSimpleResource(GetResourceType grt){
		VanHelsingStub stub;
		try {
			stub = getStub();
			
			VanHelsingStub.GetSimpleResource req = new VanHelsingStub.GetSimpleResource();
			req.setGetSimpleResource(grt);
			
			VanHelsingStub.GetSimpleResourceResponse res = stub.getSimpleResource(req);
			
			SimpleResource sr = new SimpleResource();
			sr.setResourceInfo(res.getResInfo());
			sr.setResourceAttributeType(res.getResAttribute());
			return sr;
			
			
		} catch(Exception e){
			System.err.println("getSR: " + grt.getResId() + " : " + e.toString());
		}
		return null;
	}
	/**
	 * Update or replace method for a simple resource.
	 * @param director the director on which the configuration is based on
	 * @param resourceType the name of the resource e.g. client or job
	 * @param resId the id number of the resource in the tree of the service
	 * @param replace true if the given object is to be replaced,<br/>
	 *			false if only the changed values are to be updated. 
	 * @param name name of a given resource
	 * @param keyValues containing the key-value-pairs of the resource
	 * @return	a status value of type string
	 */
	public SetSimpleResourceResponse setSimpleResource(String director, String resourceType,
			int resId, boolean replace, String name, String[][] keyValues){
		ResourceInfo resInfo = new ResourceInfo();
		resInfo.setDirector(director);
		resInfo.setResId(resId);
		resInfo.setResName(name);
		resInfo.setResType(resourceType);
		
		ResourceAttributeType[] rat = new ResourceAttributeType[keyValues.length];
		int i = 0;
		for (String [] pair : keyValues){
			rat[i].setKey(pair[0]);
			rat[i].setValue(pair[1]);
			i++;
		}
		
		ResourceInitialization ri = new ResourceInitialization();
		ri.setResInfo(resInfo);
		ri.setResAttribute(rat);
		ri.setReplace(replace);
		return setSimpleResource(ri);
	}
	/**
	 * Update or replace method for a simple resource.
	 * @param ri	ResourceInitialization contains a ResAttributeType array,<br/>
	 * 				a boolean value Replace and a ResourceInfo object
	 * @return		a string containing a status value
	 */
	public SetSimpleResourceResponse setSimpleResource(ResourceInitialization ri){
		VanHelsingStub stub;
		try {
			stub = getStub();
			
			VanHelsingStub.SetSimpleResource req = new VanHelsingStub.SetSimpleResource();
			req.setSetSimpleResource(ri);
			
			VanHelsingStub.SetSimpleResourceResponse res = stub.setSimpleResource(req);
			
			return res;
		} catch (SetSimpleResourceFault1Exception ef1){
			System.err.println("Constraint Violation");
		} catch (SetSimpleResourceFaultException ef){
			System.err.println("Syntax Error");
		} catch (Exception e) {
			System.err.println(e.toString());
		}
		return null;
	}
	/**
	 * Helper 	method to create a FileSetInclude object to be used by the<br/>
	 * 			setFileSetResource and createFileSetResource method
	 * @param fileList	file parameter list of the include component
	 * @param fsOptions options parameter list of the include component
	 * @return a FileSetInclude object
	 */
	public FileSetInclude makeFileSetInclude(ResourceAttributeType[] fileList,
			ResourceAttributeType[] fsOptions){
		FileSetInclude fsi = new FileSetInclude();
		fsi.setFileList(fileList);
		fsi.setOptions(fsOptions);
		return fsi;
	}
	/**
	 * Helper method to create a ResourceAttributeType[] out auf an ArrayList of type ViewItem
	 * @param array	ArrayList<ViewItem> containing all key value pairs
	 * @return the created ResourceAttributeType array
	 */
	public ResourceAttributeType[] makeResAttrTypeArray(ArrayList<ViewItem> array){
		array.trimToSize();
		int i = 0;
		ResourceAttributeType[] rat = new ResourceAttributeType[array.size()];
		for (ViewItem vi : array){
			rat[i] = new ResourceAttributeType();
			rat[i].setKey(vi.getKey());
			rat[i].setValue(vi.getKeyValue());
			i++;
		}
		return rat;
	}
	/**
	 * Helper method to create a ResourceAttributeType[] object out of an array of arrays of strings
	 * @param array contains the key-value-pairs which will be stored in the ResourceAttributeType[] 
	 * @return the created ResourceAttributeType array
	 */
	public ResourceAttributeType[] makeResAttrTypeArray(String[][] array){
		ResourceAttributeType[] rat = new ResourceAttributeType[array.length];
		int i = 0;
		for (String[] pair : array){
			rat[i].setKey(pair[0]);
			rat[i].setValue(pair[1]);
			i++;
		}
		return rat;
	}
	/**
	 * helper method to create a FileSetResource as an argument to the setFileSetResource method and calls said method
	 * @param replace	the object will be replaced if this parameter is set to true, otherwise the changed values will be updated
	 * @param fsi	a FileSetInclude object containing the include block of the FileSetResource
	 * @param options a ResourceAttributeType[] object containing the options block of the FileSetResource 
	 * @param exclude	a ResourceAttributeType[] object containing the exclude options
	 * @param param a ResourceAttributeType[] object containing the file set options
	 * @return a status value of type string
	 */
	public SetFileSetResourceResponse setFileSetResource(boolean replace, FileSetInclude fsi,
			ResourceAttributeType[] options, ResourceAttributeType[] exclude, 
			ResourceAttributeType[] param){
		FileSetResource fsr = new FileSetResource();
		fsr.setReplace(replace);
		fsr.setInclude(fsi);
		fsr.setOptions(options);
		fsr.setExclude(exclude);
		fsr.setParameters(param);
		return setFileSetResource(fsr);
	}
	/**
	 * Update or replace method for a file set resource.
	 * @param fsr	
	 * @return a status value of type string
	 */
	public SetFileSetResourceResponse setFileSetResource(FileSetResource fsr){
		VanHelsingStub stub;
		try {
			stub = getStub();
			VanHelsingStub.SetFileSetResource req = new VanHelsingStub.SetFileSetResource();
			req.setSetFileSetResource(fsr);
			
			VanHelsingStub.SetFileSetResourceResponse res = stub.setFileSetResource(req);
			return res;
			
		} catch (SetFileSetResourceFault1Exception ef1){
			System.err.println("Constraint Violation");
		} catch (SetFileSetResourceFaultException ef) {
			System.err.println("Syntax Error");
		} catch (Exception e){
			System.err.println(e.toString());
		}
		return null;
	}
	/**
	 * helper method for accessing the deleteResource method.
	 * @param director the director on which the configuration is based on
	 * @param resId		the id of the resource.
	 * @param resName	the name of the resource
	 * @param resType	the type of the resource
	 */
	public void deleteResource(String director, int resId, String resName, String resType){
		ResourceInfo ri = new ResourceInfo();
		ri.setDirector(director);
		ri.setResId(resId);
		ri.setResName(resName);
		ri.setResType(resType);
		deleteResource(ri);
	}
	/**
	 * deletes a resource object of any type identified by the resource id
	 * @param ri ResourceInfo object containing the identification of the resource
	 */
	public void deleteResource(ResourceInfo ri){
		VanHelsingStub stub;
		try{
			stub = getStub();
			VanHelsingStub.DeleteResource req = new VanHelsingStub.DeleteResource();
			req.setDeleteResource(ri);
			stub.deleteResource(req);
		} catch (DeleteResourceFault1Exception ef1){
			System.err.println("invalid Id");
		} catch (DeleteResourceFaultException ef){
			System.err.println("Constraint Violation");
		} catch (Exception e){
			System.err.println(e.toString());
		}
	}
	/**
	 * helper method to create a ResourceInfo object
	 * @param director the director on which the configuration is based on
	 * @param id		the id of the resource.
	 * @param name	the name of the resource
	 * @param type	the type of the resource
	 * @return new ResourceInfo object
	 */
	public ResourceInfo makeResourceInfo(String director, int id, String name, String type){
		ResourceInfo ri = new ResourceInfo();
		ri.setDirector(director);
		ri.setResId(id);
		ri.setResName(name);
		ri.setResType(type);
		return ri;
	}
	/**
	 * creates a simple resource object at Van Helsing
	 * @param replace	this parameter is part of the ResourceInitialization object but will not be used by the create method
	 * @param rat	list of key value pairs of type ResourceAttributeType[]
	 * @param rinfo		ResourceInfo object containing identification information of the object
	 * @return	Id of the created simple resource
	 */
	public int createSimpleResource(ResourceAttributeType[] rat, ResourceInfo rinfo){
		
		ResourceInitialization ri = new ResourceInitialization();
		ri.setReplace(false);
		ri.setResInfo(rinfo);
		ri.setResAttribute(rat);
		return createSimpleResource(ri);
	}
	/**
	 * creates a simple resource object at Van Helsing
	 * @param ri	ResourceInitialization object containing the needed information to create a simple resource object
	 * @return	the id of the created SimpleResource
	 */
	public int createSimpleResource(ResourceInitialization ri){
		VanHelsingStub stub;
		try {
			stub = getStub();
			VanHelsingStub.CreateSimpleResource req = new VanHelsingStub.CreateSimpleResource();
			req.setCreateSimpleResource(ri);
			
			VanHelsingStub.CreateSimpleResourceResponse res = stub.createSimpleResource(req);
			return res.getResId();
		} catch (CreateSimpleResourceFaultException ef) {
			System.err.println("Syntax Error");
		} catch (Exception e){
			System.err.println(e.toString());
		}
		return -1;
	}
	/**
	 * creates a file set resource at Van Helsing
	 * @param replace	the object will be replaced if this parameter is set to true, otherwise the changed values will be updated	
	 * @param fsi	FileSetInclude object containing the options and 
	 * @param options	list of key value pairs containing the options of a file set
	 * @param exclude	list of key value pairs containing the excluded file(types)
	 * @param param		list of key value pairs containing parameters of a file set
	 * @return	the id of the created resource
	 */
	public int createFileSetResource(boolean replace, FileSetInclude fsi,
			ResourceAttributeType[] options, ResourceAttributeType[] exclude, 
			ResourceAttributeType[] param){
		FileSetResource fsr = new FileSetResource();
		fsr.setReplace(replace);
		fsr.setInclude(fsi);
		fsr.setOptions(options);
		fsr.setExclude(exclude);
		fsr.setParameters(param);
		return createFileSetResource(fsr);
	}
	/**
	 * creates a file set object at Van Helsing
	 * @param fsr	FileSetResource object contains the needed information to create a FileSetResource
	 * @return the id of the created FileSetResource
	 */
	public int createFileSetResource(FileSetResource fsr){
		VanHelsingStub stub;
		try{
			stub = getStub();
			VanHelsingStub.CreateFileSetResource req = new VanHelsingStub.CreateFileSetResource();
			req.setCreateFileSetResource(fsr);
			
			VanHelsingStub.CreateFileSetResourceResponse res = stub.createFileSetResource(req);
			return res.getResId();
			
		} catch (CreateFileSetResourceFaultException ef){
			System.err.println();
		} catch (Exception e) {
			System.err.println(e.toString());
		}
		return -1;
	}
	/**
	 * Helper method to create a VanHelsingStub.<br/>
	 * Chunked encoding is deactivated because of ZSI.
	 * @return a stub object used by the other access methods
	 * @throws Exception
	 */
	private VanHelsingStub getStub() throws Exception {
		String url = new String("http://localhost:8080/");
		VanHelsingStub stub = new VanHelsingStub(url);
		stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
		return stub;
	}	
}
