package util.net;

import java.io.*;
import java.net.*;

/**
 * Networked Wire, Client Side.  Provides readObject, writeObject. 
 */
class SocketConnection implements Wire
{
    private Socket mySocket;
    private ObjectInputStream myInput;
    private ObjectOutputStream myOutput;


    /**
     * How to make one, if we know who we want to talk to.
     *
     * @param hostName  the name of the machine that the server is on
     * @param port      the port number on which the server is listening
     */
    public SocketConnection (Socket socket)
    {
	try
	{
	    mySocket = socket;
	    // socket protocols require that we create Output before Input
	    myOutput = new ObjectOutputStream(mySocket.getOutputStream());
	    myInput = new ObjectInputStream(mySocket.getInputStream());
	}
	catch (Exception e)
	{
	    throw new RuntimeException("");
	}
    }

    /**
     * Use this to read an Object from the Wire.
     *
     * @returns the Object read.
     */
    public Object readObject ()
    {
        try
        {
            return myInput.readObject();
        }
        catch (Exception e)
        {
            throw new RuntimeException("failed to read from " + getRemoteHostName());
        }
    }

    /**
     * Use this method to write an Object to the Wire.
     *
     * @param o The object to be written.
     */
    public void writeObject (Object o)
    {
        try
        {
            myOutput.writeObject(o);
	    myOutput.flush();
        }
        catch (IOException e)
        {
            throw new RuntimeException("failed to write to " + getRemoteHostName());
        }
    }

    public String getRemoteHostName ()
    {
	return mySocket.getInetAddress().getHostName() + ":" + mySocket.getPort();
    }


    public String getLocalHostName ()
    {
	return mySocket.getLocalAddress().getHostName() + ":" + mySocket.getLocalPort();
    }


    /**
     *  Closes the Socket and Streams.
     */
    public void finalize ()
    {
        try
        {
            myInput.close();
            myOutput.close();
            mySocket.close();
        }
        catch (IOException e)
        {}
    }
}
