package anastore.proto;

import anastore.net.SyncMessage;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.util.Collections;
import java.util.Map;

/**
 * A request for initial handshaking from the client to the server.  A
 * handshake includes a summary of all of the unbounded blocks in the
 * client's cache.  The channel opened by this message should see two
 * types of messages: {@link DeprecationRep}s and {@link
 * HandshakeRep}s.  A HandshakeRep will be sent by the server once it
 * is done sending DeprecationRep's for the blocks in the client's
 * cache.
 */
public class HandshakeReq extends SyncMessage
{
    public transient Map<Long, Long> lowerBounds;

    /**
     * Construct a handshake request from a map from block id's to
     * lower bounds.  The map <i>must not</i> be modified after it is
     * passed to this constructor.
     */
    public HandshakeReq(Map<Long, Long> lowerBounds)
    {
        this.lowerBounds = Collections.unmodifiableMap(lowerBounds);
    }

    @Override
    public String toString()
    {
        StringBuilder res = new StringBuilder("HandshakeReq<");
        Util.summarize(res, lowerBounds);
        res.append('>');
        return res.toString();
    }

    /**
     * Write the handshake request to the given output stream, using a
     * compact representation of the lower bound map.
     */
    private void writeObject(ObjectOutputStream s)
        throws IOException 
    {
        s.defaultWriteObject();
        Util.writeMapLongLong(s, lowerBounds);
    }

    /**
     * Reconstitute a handshake request.
     */
    private void readObject(ObjectInputStream s)
        throws IOException, ClassNotFoundException
    {
        s.defaultReadObject();
        lowerBounds = Collections.unmodifiableMap(Util.readMapLongLong(s));
    }
}
