package fnal.vox.security;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import org.globus.gsi.gssapi.SSLUtil;

public class ReadWriteSocket{
	private BufferedReader reader=null;
	private PrintStream writer=null;
	private InputStream in=null;
	private OutputStream out=null;
	private DataInputStream din=null;
	private DataOutputStream dout=null;
	private Socket clientSocket=null;
	private int MAXLENGTH=5000;
	

	/**
	* An object for reading and writing to the socket.
	* @param clientSocket The Socket on which read and write operation can be performed.
	*/
	public ReadWriteSocket(Socket clientSocket){
		this.clientSocket=clientSocket;
		try{
			in=clientSocket.getInputStream();
			out=clientSocket.getOutputStream();
			reader =new BufferedReader(new InputStreamReader(in));
			writer=new PrintStream(out);
			din=new DataInputStream(in);
			dout=new DataOutputStream(out);
		}catch(IOException e){
			System.out.println("Exception "+e);
		}
	}


	/**
	* A method for reading a line from the socket.
	* @return A String read from the socket input stream.
	*/
	public String readLine() throws Exception{
		String message="";
		message=reader.readLine();
		System.out.println("Recieved ---> "+message);
		return(message);
	}

	/**
	* A method for writing a line on the socket.
	* @param message A String to be written on to the socket output stream.
	*/
	public void writeLine(String message) throws Exception{
		writer.println(message);
		System.out.println("Sent ---> "+message);
	}

	
	public void writeToken(byte[] outToken) throws Exception{
		out.write(outToken);
		out.flush();
	}
	public void sendMessage(String message) throws Exception{
		byte outToken[]=message.getBytes();
		out.write(outToken);
		out.flush();
	}
	public String recvMessage() throws Exception{
		String line="";
		char buf[]=new char[MAXLENGTH];
		int len=reader.read(buf,0,MAXLENGTH-1);
		//System.out.println("len is "+len);
		char toReturn[]=new char[len];
		for(int i=0;i<len;i++){
			toReturn[i]=buf[i];
		}
		return(String.valueOf(toReturn));
	}

	/*public byte[] readToken() throws Exception{
		byte[] inToken=new byte[100000];
		byte[] toReturn=null;
		int length=in.read(inToken);
		toReturn=new byte[length];
		System.out.println("length of token read is "+length);
		for(int i=0;i<length;i++){
			System.out.print(Byte.toString(inToken[i]));
			toReturn[i]=inToken[i];
		}
		System.out.println();
		return(toReturn);
	}*/

	public byte[] readToken() throws Exception{
		return(SSLUtil.readSslMessage(in));
		/*byte[] inToken=new byte[100000];
		byte[] toReturn=null;
		int length=in.read(inToken,0,size);
		if(length==-1){
			return(null);
		}
		toReturn=new byte[length];
		//System.out.println("length of token read is "+length);
		for(int i=0;i<length;i++){
			//System.out.print(Byte.toString(inToken[i]));
			toReturn[i]=inToken[i];
		}

		return(toReturn);*/
	}


	/*public byte[] readTokennew() throws Exception{
		byte[] inToken=new byte[100000];
		byte[] temp=new byte[100000];
		byte[] toReturn=null;
		int length=-2;
		int index=0;
		//while((length!=-1)&&(length!=0)){
		for(int k=0;k<1000;k++){
			System.out.println("bytes that are available "+in.available());
			if(in.available()>0){
				System.out.println("jest beforr read");
				length=in.read(inToken);
				System.out.println("length of token read is "+length);
				for(int i=0;i<length;i++){
				//System.out.print(Byte.toString(inToken[i]));
					temp[index]=inToken[i];
					index++;
				}
			}
		}
		toReturn=new byte[index];
		for(int i=0;i<index;i++){
			toReturn[i]=temp[i];
		}

		return(toReturn);
	}*/


	public byte[] readKerberosToken() throws Exception{
		byte[] token=new byte[din.readInt()];
		din.readFully(token);
		return(token);
	}
	
	public void writeKerberosToken(byte[] token) throws Exception{
		dout.writeInt(token.length);
		dout.write(token);
		dout.flush();
	}

	/**
	* A method for closing both the input and output stream of the socket.
	*/
	public void closeAll(){
		try{
			reader.close();
			writer.close();
			din.close();
			dout.close();

		}catch(IOException e){
			System.out.println("Exception "+e);
		}

	}
	
}
