package com.jscape.util.net;

import com.jscape.util.Time;

import static com.jscape.util.Parameters.assertGreaterOrEqual;
import static com.jscape.util.Parameters.assertNotNull;

/**
 * @author Alex Usun
 */
public class ConnectionDescriptor {

    private TransportAddress localAddress;
    private TransportAddress remoteAddress;
    private long timeout;

    public ConnectionDescriptor(TransportAddress localAddress, TransportAddress remoteAddress, long timeoutMillis) {
        this.localAddress = localAddress;

        assertNotNull(remoteAddress);
        this.remoteAddress = remoteAddress;

        assertGreaterOrEqual(timeoutMillis, 0, "Bad timeout value.");
        this.timeout = timeoutMillis;
    }

    public ConnectionDescriptor(TransportAddress localAddress, TransportAddress remoteAddress, Time timeout) {
        this(localAddress, remoteAddress, timeout.toMillis());
    }

    public ConnectionDescriptor(TransportAddress remoteAddress, long timeoutMillis) {
        this(null, remoteAddress, timeoutMillis);
    }

    public ConnectionDescriptor(TransportAddress remoteAddress, Time timeout) {
        this(remoteAddress, timeout.toMillis());
    }

    public ConnectionDescriptor(ConnectionDescriptor that) {
        this(that.localAddress != null ? new TransportAddress(that.localAddress) : null,
             new TransportAddress(that.remoteAddress),
             that.timeout);
    }

    public ConnectionDescriptor() {
        // empty
    }

    public TransportAddress getLocalAddress() {
        return this.localAddress;
    }

    public void setLocalAddress(TransportAddress value) {
        this.localAddress = value;
    }

    public TransportAddress getRemoteAddress() {
        return this.remoteAddress;
    }

    public void setRemoteAddress(TransportAddress value) {
        assertNotNull(value);
        this.remoteAddress = value;
    }

    public long getTimeout() {
        return this.timeout;
    }

    public void setTimeout(long value) {
        assertGreaterOrEqual(value, 0, "Bad timeout value.");
        this.timeout = value;
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        ConnectionDescriptor that = (ConnectionDescriptor) o;

        return this.remoteAddress.equals(that.remoteAddress);
    }

    public int hashCode() {
        return this.remoteAddress.hashCode();
    }

    public String toString() {
        return "ConnectionDescriptor {"
                + "localAddress=" + this.localAddress
                + ", remoteAddress=" + this.remoteAddress
                + ", timeout=" + this.timeout
                + "}";
    }
}
