package org.onosproject.net.tunnel;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Objects;

import org.onosproject.core.ApplicationId;
import org.onosproject.net.AbstractAnnotated;
import org.onosproject.net.Annotations;
import org.onosproject.net.tunnel.Tunnel.Type;

import com.google.common.base.MoreObjects;

/**
 * Represents for a order that consumer subscribe tunnel. ONOS maintains request
 * information, it means ONOS knows how much resource echo consumer uses in the
 * ONOS. Although there is no a tunnel that consumer want to use, when producer
 * creates a new tunnel, ONOS will notify the consumers that want to use it.
 */
public final class TunnelSubscription extends AbstractAnnotated {
    private final ApplicationId consumerId;
    private final TunnelEndPoint src;
    private final TunnelEndPoint dst;
    private final Type type;
    private final TunnelId tunnelId;
    private final TunnelName tunnelName;

    /**
     * Creates a TunnelSubscription.
     *
     * @param consumerId consumer identity
     * @param src source tunnel end point of tunnel
     * @param dst destination tunnel end point of tunnel
     * @param tunnelId tunnel identity
     * @param type tunnel type
     * @param tunnelName the name of a tunnel
     * @param annotations parameter
     */
    public TunnelSubscription(ApplicationId consumerId, TunnelEndPoint src,
                 TunnelEndPoint dst, TunnelId tunnelId, Type type,
                 TunnelName tunnelName, Annotations... annotations) {
        super(annotations);
        checkNotNull(consumerId, "consumerId cannot be null");
        this.consumerId = consumerId;
        this.src = src;
        this.dst = dst;
        this.type = type;
        this.tunnelId = tunnelId;
        this.tunnelName = tunnelName;
    }

    /**
     * Returns consumer identity.
     *
     * @return consumerId consumer id
     */
    public ApplicationId consumerId() {
        return consumerId;
    }

    /**
     * Returns source point of tunnel.
     *
     * @return source point
     */
    public TunnelEndPoint src() {
        return src;
    }

    /**
     * Returns destination point of tunnel.
     *
     * @return destination point
     */
    public TunnelEndPoint dst() {
        return dst;
    }

    /**
     * Returns tunnel type.
     *
     * @return tunnel type
     */
    public Type type() {
        return type;
    }

    /**
     * Returns tunnel identity.
     *
     * @return tunnel id
     */
    public TunnelId tunnelId() {
        return tunnelId;
    }

    /**
     * Returns tunnel name.
     *
     * @return tunnel name
     */
    public TunnelName tunnelName() {
        return tunnelName;
    }

    @Override
    public int hashCode() {
        return Objects.hash(consumerId, src, dst, type, tunnelId, tunnelName);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof TunnelSubscription) {
            final TunnelSubscription other = (TunnelSubscription) obj;
            return Objects.equals(this.src, other.src)
                    && Objects.equals(this.dst, other.dst)
                    && Objects.equals(this.consumerId, other.consumerId)
                    && Objects.equals(this.type, other.type)
                    && Objects.equals(this.tunnelId, other.tunnelId)
                    && Objects.equals(this.tunnelName, other.tunnelName);
        }
        return false;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("src", src)
                .add("dst", dst)
                .add("consumerId", consumerId)
                .add("type", type)
                .add("tunnelId", tunnelId)
                .add("tunnelName", tunnelName).toString();
    }
}
