package utility;
import java.util.*;
import java.io.*;
import java.net.*;




public abstract class DataServerHandler implements Runnable
{


	protected Thread t = null;
  	protected Hashtable connections = new Hashtable();
	protected Hashtable connectionHandlers = new Hashtable();
  	protected Vector  ids = new Vector();
	public DataServerHandler()
	{
		t=new Thread(this);
		t.start();
	}

	synchronized public Vector getConnectionsIds()
	{
    		Vector cids = new Vector();
    		Enumeration e = connections.keys();
    		while (e.hasMoreElements())
		{
      			cids.addElement((Integer)e.nextElement());
    		}
    		return cids;
  	}


  	synchronized public void addConnection(AgentIdentity id, InputStream in, OutputStream out)
	{

			System.out.println("Starting connection for "+id.getLoginName());
			connections.put(new Integer(id.getId()), new Connection(in, out));
    			//DataConnectionHandler connHandler = new DataConnectionHandler(id, this);
        		//connectionHandlers.put(new Integer(id.getId()), connHandler);
  			ids.addElement(id);

	}


  	synchronized public   boolean removeConnection(AgentIdentity aId)
	{
		return removeConnection(aId.getId());

	}

	synchronized public boolean removeConnection(int cid)
	{
    		boolean success = false;
    		/*DataConnectionHandler connHandler = (DataConnectionHandler) connectionHandlers.remove(new Integer(cid));
		if (t != null && connections.remove(new Integer(cid)) != null)
		{
      			connHandler.stop= true;
      			success = true;
    		}*/
		connections.remove(new Integer(cid));
		return success;
	}

  	synchronized protected Connection getConnection(int cid)
	{
    		return (Connection)connections.get(new Integer(cid));
  	}

	synchronized protected int getConnectionId(AgentIdentity id)
	{

    		int cid = -1;
		Enumeration e = ids.elements();
    		while (e.hasMoreElements())
		{
      			AgentIdentity aid = (AgentIdentity)e.nextElement() ;

			if(id.getLoginName().compareTo(aid.getLoginName()) == 0)
			{
				cid = aid.getId();
			}
    		}
    		return cid;
  	}

	public  boolean readStream(AgentIdentity id) throws IOException
	{
		return false;
	}
	public abstract boolean readStream(AgentIdentity id, String fileName) throws IOException;
	/*public boolean readStream(AgentIdentity id) throws IOException
	{
    		boolean result = false;

    		Connection conn = getConnection(id.getId());
    		System.out.println("waiting 4 connection to be established");
		while(conn == null)
		{
			conn = getConnection(id.getId());
		}
		System.out.println("client connected");
		if (conn != null)
		{
      			ClientHeader receivedRequest = null;
			synchronized (conn.in)
			{
          			BufferedInputStream buffIn = null;
				try
				{
					buffIn = new BufferedInputStream(conn.in);
					byte buff[] = new byte[40];
					int next =0;
					System.out.println("File input from Agent :" +id.getLoginName());
					while((next = buffIn.read(buff,0,buff.length)) != -1)
					{
						System.out.print(new String(buff,0,next));
					}
					result = true;
					buffIn.close();
					System.out.println("closing buffered stream");
					removeConnection(id);
					conn.in.close();
					conn.out.close();

				}
				catch (StreamCorruptedException e)
				{
					System.out.println(e + " : closing it(1)");
					removeConnection(id);
					result = false;
				}


				catch (java.lang.NullPointerException e)
				{
					System.out.println( e + " : closing it(3)");
					removeConnection(id.getId());
					result = false;
				}
				catch (SocketException e)
				{
					e.printStackTrace();
					removeConnection(id);
				}
				catch (Exception e)
				{
					e.printStackTrace();
					removeConnection(id.getId());
					result = false;
				}
			}
		}
		return result;
	}*/


	public abstract boolean sendStream(String fileName, int cid) throws IOException;
  	/*{
    		boolean success = true;
    		Connection conn = getConnection(cid);
    		if (conn != null)
		{
      			//System.out.println("Trying to lock on connection" + cid);
        		synchronized (conn.out)
			{
          			//System.out.println("Got lock on connection " + cid);
          			BufferedOutputStream buffOut = null;
				try
				{
					buffOut = new BufferedOutputStream(conn.out);
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
				try
				{
					File f = new File(fileName);
					byte buff[] = new byte [40];
					FileInputStream inFileStream = new FileInputStream (f);
					BufferedInputStream inBuffStream = new BufferedInputStream(inFileStream);
					//BufferedOutputStream outBuffStream = new BufferedOutputStream (cli.getOutputStream());
					int next =0;
					while((next =( inBuffStream.read ( buff,0,buff.length ) )) != -1)
					{

						//System.out.print(new String(buff,0,next));
						buffOut.write(buff,0,next);
						buffOut.flush();
					}
				}
				catch (Exception e)
				{
					success = false;
					e.printStackTrace();
				}
				//if(success)
				//	System.out.println("writeObject successfull");
			}
		}

		return success;
	}*/

	public void run()
	{
	}



	synchronized public int nextConnectionId()
	{
		int nextId = connections.size();
		for(int i=0 ;i<connections.size();i++)
		{
			if(! connections.containsKey(new Integer(i)))
			{
				nextId = i;
				break;
			}
		}
  		return nextId;
	}
	//abstract public void doThis(Request req ,AgentIdentity id);

}
