package client.backend;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import shared.communication.*;

public class ClientsideCommunicator
{
	String host = null, port = null;
	
	public ClientsideCommunicator(String host, String port)
	{
		this.host = host;
		this.port = port;
	}

	public ValidateUserResponse validateUser(String userName, String password)
	{
		ValidateUserRequest req = new ValidateUserRequest(userName, password);
		ValidateUserResponse output = (ValidateUserResponse)doPost("ValidateUser", req);
		
		return output;
	}
	
	public GetProjectsResponse getProjects(String userName, String password)
	{
		GetProjectsRequest req = new GetProjectsRequest(userName, password);
		GetProjectsResponse output = (GetProjectsResponse)doPost("GetProjects", req);
		
		return output;
	}
	
	public GetSampleImageResponse getSampleImage(String userName, String password, int projectID)
	{
		GetSampleImageRequest req = new GetSampleImageRequest(userName, password, projectID);
		GetSampleImageResponse output = (GetSampleImageResponse)doPost("GetSampleImage", req);
		
		return output;
	}
	
	public DownloadBatchResponse downloadBatch(String userName, String password, int projectID)
	{
		DownloadBatchRequest req = new DownloadBatchRequest(userName, password, projectID);
		DownloadBatchResponse output = (DownloadBatchResponse)doPost("DownloadBatch", req);
		
		return output;
	}
	
	public GetFieldsResponse getFields(String userName, String password, int projectID)
	{
		GetFieldsRequest req = new GetFieldsRequest(userName, password, projectID);
		GetFieldsResponse output = (GetFieldsResponse)doPost("GetFields", req);
		
		return output;
	}
	
	public boolean submitBatch(String userName, String password, int batchID, List<String> values)
	{
		SubmitBatchRequest req = new SubmitBatchRequest(userName, password, batchID, values);
		Boolean output = (Boolean)doPost("SubmitBatch", req);
		
		if(output == null)
		{
			return false;
		}
		return output;
	}
	
	public SearchResponse search(String userName, String password, List<Integer> fields, List<String> targets)
	{
		SearchRequest req = new SearchRequest(userName, password, fields, targets);
		SearchResponse output = (SearchResponse)doPost("Search", req);
		
		return output;
	}
	
	public byte[] download(String filePath)
	{
		return (byte[])doPost(filePath, null);
	}
	
	private Object doPost(String command, Object toPost)
	{
		Object output = null;
		
		HttpURLConnection conn = null;
		try
		{
			// Establish connection.
			URL url = new URL("http://" + host + ":" + port + "/" + command);
			conn = (HttpURLConnection)url.openConnection();
			
			conn.setRequestMethod("POST");
			conn.setDoInput(true);
			conn.setDoOutput(true);
			
			conn.connect();
			
			// Serialize and send data.
			XStream xStr = new XStream(new DomDriver());
			xStr.toXML(toPost, conn.getOutputStream());
			
			// Get response.
			if(conn.getResponseCode() == HttpURLConnection.HTTP_OK)
			{
				output = xStr.fromXML(conn.getInputStream());
			}
			
			conn.disconnect();
		}
		catch(Exception e)
		{
			output = null;
			System.out.println("WARNING: Error in connection to server.");
			e.printStackTrace();
		}
		
		return output;
	}
}
