package net.onrc.onos.core.topology;

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

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.topology.web.serializers.HostDataSerializer;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.SwitchPort;

import org.codehaus.jackson.map.annotate.JsonSerialize;

/**
 * Self-contained Host object.
 */
@JsonSerialize(using = HostDataSerializer.class)
public class HostData extends TopologyElement<HostData> {

    private final MACAddress mac;
    private final int ip;
    private List<SwitchPort> attachmentPoints;
    private long lastSeenTime;

    /**
     * Default constructor for Serializer to use.
     */
    @Deprecated
    protected HostData() {
        mac = null;
        ip = 0;
    }

    /**
     * Constructor for a given host MAC address.
     *
     * @param mac the MAC address to identify the host
     */
    public HostData(MACAddress mac, int ip) {
        this.mac = checkNotNull(mac);
        this.ip = ip;
        this.attachmentPoints = new LinkedList<>();
    }

    /**
     * Copy constructor.
     * <p>
     * Creates an unfrozen copy of the given HostData object.
     *
     * @param original the object to make copy of
     */
    public HostData(HostData original) {
        super(original);
        this.mac = original.mac;
        this.ip = original.ip;
        this.attachmentPoints = new ArrayList<>(original.attachmentPoints);
        this.lastSeenTime = original.lastSeenTime;
    }

    /**
     * Gets the host MAC address.
     *
     * @return the MAC address.
     */
    public MACAddress getMac() {
        return mac;
    }

    /**
     * Gets the host IP address.
     *
     * @return the IP address.
     */
    public int getIp() {
        return ip;
    }

    /**
     * Gets the switch attachment points.
     *
     * @return the switch attachment points
     */
    public List<SwitchPort> getAttachmentPoints() {
        return Collections.unmodifiableList(attachmentPoints);
    }

    /**
     * Sets the switch attachment points.
     *
     * @param attachmentPoints the switch attachment points to set
     */
    public void setAttachmentPoints(List<SwitchPort> attachmentPoints) {
        if (isFrozen()) {
            throw new IllegalStateException("Tried to modify frozen instance: " + this);
        }
        this.attachmentPoints = attachmentPoints;
    }

    /**
     * Adds a switch attachment point.
     *
     * @param attachmentPoint the switch attachment point to add
     */
    public void addAttachmentPoint(SwitchPort attachmentPoint) {
        if (isFrozen()) {
            throw new IllegalStateException("Tried to modify frozen instance: " + this);
        }
        // may need to maintain uniqueness
        this.attachmentPoints.add(0, attachmentPoint);
    }

    /**
     * Removes a switch attachment point.
     *
     * @param attachmentPoint the switch attachment point to remove
     */
    public boolean removeAttachmentPoint(SwitchPort attachmentPoint) {
        if (isFrozen()) {
            throw new IllegalStateException("Tried to modify frozen instance: " + this);
        }
        return this.attachmentPoints.remove(attachmentPoint);
    }

    /**
     * Gets the host last seen time in milliseconds since the epoch.
     *
     * @return the host last seen time in milliseconds since the epoch
     */
    public long getLastSeenTime() {
        return lastSeenTime;
    }

    /**
     * Sets the host last seen time in milliseconds since the epoch.
     *
     * @param lastSeenTime the host last seen time in milliseconds since the
     * epoch
     */
    public void setLastSeenTime(long lastSeenTime) {
        if (isFrozen()) {
            throw new IllegalStateException("Tried to modify frozen instance: " + this);
        }
        this.lastSeenTime = lastSeenTime;
    }

    /**
     * Computes the host ID for a given host MAC address.
     * <p>
     * TODO: This method should be replaced with a method that uses
     * MACAddress as an argument instead of a byte array.
     *
     * @param mac the host MAC address to use
     * @return the host ID as a ByteBuffer
     */
    public static ByteBuffer getHostID(final byte[] mac) {
        return (ByteBuffer) ByteBuffer.allocate(2 + mac.length)
                .putChar('H').put(mac).flip();
    }

    @Override
    public Dpid getOriginDpid() {
        // TODO: Eventually, we should return a collection of Dpid values
        for (SwitchPort sp : attachmentPoints) {
            return sp.getDpid();
        }
        return null;
    }

    @Override
    public ByteBuffer getIDasByteBuffer() {
        return getHostID(mac.toBytes());
    }

    @Override
    public int hashCode() {
        return 31 * super.hashCode() + Objects.hash(attachmentPoints, mac);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        // Compare attributes
        if (!super.equals(o)) {
            return false;
        }

        HostData other = (HostData) o;
        // XXX lastSeenTime excluded from Equality condition, is it OK?
        return Objects.equals(mac, other.mac) &&
                ip == other.ip &&
                Objects.equals(this.attachmentPoints, other.attachmentPoints);
    }

    @Override
    public String toString() {
        return "[HostData " + mac + "(ip:" + ip + ")" + " attachmentPoints:" + attachmentPoints + "]";
    }
}
