import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.Socket;

/*
 * Deals with communicating with the Server
 */
public class ClientServerSync {

	private DataInputStream input=null;
	private BufferedOutputStream output=null;

	//Initial connection set-up. Determines if a registration request should be sent.
	public String connect(String mac_address, String file_name){
		System.out.println("Tryin to connect");
		System.out.println("Registration ID:"+PropertyFileValues.registrationid);
		if((PropertyFileValues.registrationid).equals("nullregisterid")){
			System.out.println("Tryin to register");
			if (registerWithServer(mac_address).contains("registration success")){
				System.out.println("registration successful");
				return sendFile(file_name);
			}
			else{
				return "registration failure";
			}
		}
		return sendFile(file_name);
	}


	//Send registration request to the server
	public String registerWithServer(String mac_address){
		try {
			Socket socket = new Socket(PropertyFileValues.llamaserver, 8080);
			input=new DataInputStream(socket.getInputStream());
			output = new BufferedOutputStream( socket.getOutputStream() );
			byte [] output_string = ("Registration request:"+mac_address+"/").getBytes();
			for(int i=0;i<output_string.length;i++)
				output.write(output_string[i]);
			output.flush();
			String result = input.readUTF();
			System.out.println(result);
			input.close();
			socket.close();
			if (!result.equals("registration failed")){
				storeRegistrationID(result);
				PropertyFileValues.registrationid = result;
				return "registration success";
			}
			else{
				return "registration failure";
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "registration failure";
		}
	}


	//Upload data files on the hard disk to the server
	public String sendFile(String file_name){
		try {
			System.out.println("Sending file");
			Socket socket = new Socket(PropertyFileValues.llamaserver, 8080);
			output = new BufferedOutputStream( socket.getOutputStream() );
			byte [] output_string = ("File Transfer:"+PropertyFileValues.registrationid+"*"+file_name+"/").getBytes();
			for(int i=0;i<output_string.length;i++)
				output.write(output_string[i]);	            
			input=new DataInputStream(socket.getInputStream());
			output.flush();
			String result = input.readUTF();
			System.out.println("result after file transfer request"+result);
			input.close();
			socket.close();
			if (result.equals("failure")){
				socket.close();
				return "file transfer failure";
			}

			Socket file_socket = new Socket(PropertyFileValues.llamaserver, 8081);
			FileInputStream fis = new FileInputStream(PropertyFileValues.destination_dir+"\\"+file_name);
			BufferedInputStream in = new BufferedInputStream(fis);
			BufferedOutputStream out = new BufferedOutputStream( file_socket.getOutputStream() );
			int i;
			while ((i = in.read()) != -1) {
				out.write(i);
			}
			out.flush();
			out.close();
			input.close();
			in.close();
			socket.close();
		}
		catch( Exception e ) {
			System.out.print("Error! It didn't work! " + e + "\n");
			return "false";
		}
		return "success";
	}


	//Stores the registration ID provided by the server into the ClientValues.properties file
	public void storeRegistrationID(String reg_id){
		StringBuffer sb = new StringBuffer(1024);
		try {
			BufferedReader reader = new BufferedReader(new FileReader("ClientValues.properties"));		
			char[] chars = new char[1024];
			while( (reader.read(chars)) > -1){
				sb.append(String.valueOf(chars));	
			}
			reader.close();

			BufferedWriter writer = new BufferedWriter(new FileWriter("ClientValues.properties"));
			writer.write(sb.toString().replace("nullregisterid",reg_id));
			writer.flush();
			writer.close();	
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


}
