package anastore.net;

import anastore.util.*;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * Client for the channel abstraction. This class connects to a remote
 * host (running a ChannelServer, presumably), and establishes send
 * and receive channels.
 *
 * connect() returns as soon as the connection has been established,
 * and spawns off a thread to handle receiving and dispatching
 * incoming messages.
 */
public class ChannelClient {

    private String hostname;
    private int port;
    private Socket socket;
    private CountingOutputStream countOS;

    /**
     * Create a new client, but do not connect yet.
     *
     * @param hostname hostname of the host to connect to
     * @param port port of the host to connect to
     */
    public ChannelClient(String hostname, int port) {
        this.hostname = hostname;
        this.port = port;
    }

    /**
     * Establish the connection and return the root send and receive
     * channels, spawning off a thread to service this connection.
     *
     * @throws IOException if an error occurred while connecting
     * @throws UnknownHostException if hostname unknown
     */
    public Pair<SendChannel, ReceiveChannel> connect()
        throws IOException, UnknownHostException {
        return connect(null);
    }

    /**
     * Like {@link #connect()}, but track sent and received
     * statistics.
     */
    public Pair<SendChannel, ReceiveChannel> connect(StreamStatistics stats)
        throws IOException, UnknownHostException {

        // Make the connection
        socket = new Socket(hostname, port);

        // Start a thread to service it
        ChannelProtocolThread thread =
            new ChannelProtocolThread(socket, hostname, port, stats);
        thread.start();

        // Get the send and receive channels
        SendChannel send = thread.getRootSendChannel();
        ReceiveChannel recv = thread.getRootReceiveChannel();
        return new Pair<SendChannel, ReceiveChannel>(send, recv);
    }
}
