package net.onrc.onos.core.topology;

import java.util.Map;

import net.onrc.onos.core.util.LinkTuple;

import org.apache.commons.lang.Validate;

/**
 * Link Object stored in In-memory Topology.
 * <p/>
 * TODO REMOVE following design memo: This object itself may hold the DBObject,
 * but this Object itself will not issue any read/write to the DataStore.
 */
public class LinkImpl extends TopologyObject implements Link {

    //////////////////////////////////////////////////////
    /// Topology element attributes
    ///  - any changes made here needs to be replicated.
    //////////////////////////////////////////////////////
    private LinkEvent linkObj;


    /**
     * Creates a Link object based on {@link LinkEvent}.
     *
     * @param topology Topology instance this object belongs to
     * @param scPort self contained {@link LinkEvent}
     */
    public LinkImpl(Topology topology, LinkEvent scPort) {
        super(topology);
        Validate.notNull(scPort);

        // TODO should we assume linkObj is already frozen before this call
        //      or expect attribute update will happen after .
        if (scPort.isFrozen()) {
            this.linkObj = scPort;
        } else {
            this.linkObj = new LinkEvent(scPort);
            this.linkObj.freeze();
        }
    }

    /**
     * Creates a Link object with empty attributes.
     *
     * @param topology Topology instance this object belongs to
     * @param srcPort source port
     * @param dstPort destination port
     */
    public LinkImpl(Topology topology, Port srcPort, Port dstPort) {
        this(topology,
             new LinkEvent(srcPort.asSwitchPort(),
                           dstPort.asSwitchPort()).freeze());
    }

    @Override
    public LinkTuple getLinkTuple() {
        return linkObj.getLinkTuple();
    }

    @Override
    public Switch getSrcSwitch() {
        topology.acquireReadLock();
        try {
            return topology.getSwitch(linkObj.getSrc().getDpid());
        } finally {
            topology.releaseReadLock();
        }
    }

    @Override
    public Port getSrcPort() {
        topology.acquireReadLock();
        try {
            return topology.getPort(linkObj.getSrc());
        } finally {
            topology.releaseReadLock();
        }
    }

    @Override
    public Switch getDstSwitch() {
        topology.acquireReadLock();
        try {
            return topology.getSwitch(linkObj.getDst().getDpid());
        } finally {
            topology.releaseReadLock();
        }
    }

    @Override
    public Port getDstPort() {
        topology.acquireReadLock();
        try {
            return topology.getPort(linkObj.getDst());
        } finally {
            topology.releaseReadLock();
        }
    }

    @Override
    public long getLastSeenTime() {
        // TODO Auto-generated method stub
        throw new UnsupportedOperationException("Not implemented yet");
    }

    @Override
    public Double getCapacity() {
        return this.linkObj.getCapacity();
    }

    void setCapacity(Double capacity) {
        if (this.linkObj.isFrozen()) {
            this.linkObj = new LinkEvent(this.linkObj);
            this.linkObj.setCapacity(capacity);
            this.linkObj.freeze();
        } else {
            this.linkObj.setCapacity(capacity);
        }
    }

    // XXX actually replaces everything
    void replaceStringAttributes(LinkEvent updated) {
        Validate.isTrue(this.linkObj.getSrc().equals(updated.getSrc()),
                "Wrong LinkEvent given.");
        Validate.isTrue(this.linkObj.getDst().equals(updated.getDst()),
                "Wrong LinkEvent given.");

        // XXX simply replacing whole self-contained object for now
        if (updated.isFrozen()) {
            this.linkObj = updated;
        } else {
            this.linkObj = new LinkEvent(updated).freeze();
        }
    }


    @Override
    public String getStringAttribute(String attr) {
        return linkObj.getStringAttribute(attr);
    }

    @Override
    public String getStringAttribute(String attr, String def) {
        final String v = getStringAttribute(attr);
        if (v == null) {
            return def;
        } else {
            return v;
        }
    }

    @Override
    public Map<String, String> getAllStringAttributes() {
        return linkObj.getAllStringAttributes();
    }

    @Override
    public String toString() {
        return String.format("%s --(cap:%f Mbps)--> %s",
                getSrcPort().toString(),
                getCapacity(),
                getDstPort().toString());
    }


    /**
     * Returns the type of topology object.
     *
     * @return the type of the topology object
     */
    @Override
    public String getType() {
        return getStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_PACKET_LAYER);
    }
}
