package net.onrc.onos.core.datastore.topology;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import net.onrc.onos.core.datastore.DataStoreClient;
import net.onrc.onos.core.datastore.IKVTable.IKVEntry;
import net.onrc.onos.core.datastore.serializers.Topology.PortProperty;
import net.onrc.onos.core.datastore.utils.ByteArrayUtil;
import net.onrc.onos.core.datastore.utils.KVObject;
import net.onrc.onos.core.topology.PortEvent;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.PortNumber;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.esotericsoftware.kryo.Kryo;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;

/**
 * Port object in data store.
 * <p/>
 * Note: This class will not maintain invariants.
 * e.g., It will NOT automatically remove Links or Devices on Port,
 * when deleting a Port.
 */
public class KVPort extends KVObject {
    private static final Logger log = LoggerFactory.getLogger(KVPort.class);

    private static final ThreadLocal<Kryo> PORT_KRYO = new ThreadLocal<Kryo>() {
        @Override
        protected Kryo initialValue() {
            Kryo kryo = new Kryo();
            kryo.setRegistrationRequired(true);
            kryo.setReferences(false);
            kryo.register(byte[].class);
            kryo.register(byte[][].class);
            kryo.register(HashMap.class);
            // TODO check if we should explicitly specify EnumSerializer
            kryo.register(STATUS.class);
            return kryo;
        }
    };

    static final String PORT_TABLE_SUFFIX = ":Port";

    // must not re-order enum members, ordinal will be sent over wire
    /**
     * Status.
     */
    public enum STATUS {
        INACTIVE, ACTIVE;
    }

    private final Long dpid;
    private final Long number;

    private STATUS status;

    /**
     * Generate a PortID from port pair (dpid, number).
     *
     * @param dpid DPID of a switch it reside on.
     * @param number port number of this
     * @return PortID
     */
    public static byte[] getPortID(final Dpid dpid, final PortNumber number) {
        return PortEvent.getPortID(dpid, number).array();
    }

    /**
     * Generate a PortID from port pair (dpid, number).
     *
     * @param dpid DPID of a switch it reside on.
     * @param number port number of this
     * @return PortID
     */
    public static byte[] getPortID(final Long dpid, final Long number) {
        return PortEvent.getPortID(dpid, number).array();
    }

    /**
     * Gets the port pair from PortID.
     *
     * @param key PortID
     * @return port pair (dpid, number)
     */
    public static long[] getPortPairFromKey(final byte[] key) {
        return getPortPairFromKey(ByteBuffer.wrap(key));
    }

    /**
     * Gets the port pair from PortID.
     *
     * @param keyBuf PortID
     * @return port pair (dpid, number)
     */
    public static long[] getPortPairFromKey(final ByteBuffer keyBuf) {
        if (keyBuf.getChar() != 'S') {
            throw new IllegalArgumentException("Invalid Port key:" + keyBuf
                    + " "
                    + ByteArrayUtil.toHexStringBuilder(keyBuf.array(), ":"));
        }
        long[] pair = new long[2];
        pair[0] = keyBuf.getLong();
        if (keyBuf.getChar() != 'P') {
            throw new IllegalArgumentException("Invalid Port key:" + keyBuf
                    + " "
                    + ByteArrayUtil.toHexStringBuilder(keyBuf.array(), ":"));
        }
        pair[1] = keyBuf.getLong();
        return pair;

    }

    /**
     * Gets the port number from PortID.
     *
     * @param key PortID
     * @return port number
     */
    public static long getDpidFromKey(final byte[] key) {
        return getPortPairFromKey(key)[0];
    }

    /**
     * Gets the dpid of an switch from PortID.
     *
     * @param key PortID
     * @return dpid
     */
    public static long getNumberFromKey(final byte[] key) {
        return getPortPairFromKey(key)[1];
    }

    /**
     * KVPort constructor for default namespace.
     *
     * @param dpid DPID of the switch this port is on
     * @param number port number of this port
     */
    public KVPort(final Long dpid, final Long number) {
        this(dpid, number, DEFAULT_NAMESPACE);
    }

    /**
     * KVPort constructor for specified namespace.
     *
     * @param dpid DPID of the switch this port is on
     * @param number port number of this port
     * @param namespace namespace to create this object
     */
    public KVPort(final Long dpid, final Long number, final String namespace) {
        super(DataStoreClient.getClient()
                .getTable(namespace + PORT_TABLE_SUFFIX),
                getPortID(dpid, number), namespace);

        this.dpid = dpid;
        this.number = number;
        this.status = STATUS.INACTIVE;
    }

    /**
     * KVPort constructor for default namespace.
     *
     * @param dpid DPID of the switch this port is on
     * @param number port number of this port
     */
    public KVPort(final Dpid dpid, final PortNumber number) {
        this(dpid, number, DEFAULT_NAMESPACE);
    }

    /**
     * KVPort constructor for specified namespace.
     *
     * @param dpid DPID of the switch this port is on
     * @param number port number of this port
     * @param namespace namespace to create this object
     */
    public KVPort(final Dpid dpid, final PortNumber number, final String namespace) {
        this(dpid.value(), (long) number.value(), namespace);
    }

    /**
     * Gets an instance from PortID in default namespace.
     * <p/>
     * Note: You need to call `read()` to get the DB content.
     *
     * @param key PortID
     * @return {@link KVPort} instance
     */
    public static KVPort createFromKey(final byte[] key) {
        return createFromKey(key, DEFAULT_NAMESPACE);
    }

    /**
     * Gets an instance from PortID in specified namespace.
     * <p/>
     * Note: You need to call `read()` to get the DB content.
     *
     * @param key PortID
     * @param namespace namespace to create this object.
     * @return {@link KVPort} instance
     */
    public static KVPort createFromKey(final byte[] key, final String namespace) {
        long[] pair = getPortPairFromKey(key);
        return new KVPort(pair[0], pair[1], namespace);
    }

    /**
     * Gets all the Ports in default namespace.
     *
     * @return Ports
     */
    public static Iterable<KVPort> getAllPorts() {
        return getAllPorts(DEFAULT_NAMESPACE);
    }

    /**
     * Gets all the Ports in specified namespace.
     *
     * @param namespace namespace to iterate over
     * @return Ports
     */
    public static Iterable<KVPort> getAllPorts(final String namespace) {
        return new PortEnumerator(namespace);
    }

    /**
     * Utility class to provide Iterable interface.
     */
    public static class PortEnumerator implements Iterable<KVPort> {

        private final String namespace;

        /**
         * Constructor to iterate Ports in specified namespace.
         *
         * @param namespace namespace to iterate through
         */
        public PortEnumerator(final String namespace) {
            this.namespace = namespace;
        }

        @Override
        public Iterator<KVPort> iterator() {
            return new PortIterator(namespace);
        }
    }

    /**
     * Utility class to provide Iterator over all the Port objects.
     */
    public static class PortIterator extends AbstractObjectIterator<KVPort> {

        /**
         * Constructor to create an iterator to iterate all the Ports
         * in specified namespace.
         *
         * @param namespace namespace to iterate through
         */
        public PortIterator(final String namespace) {
            super(DataStoreClient.getClient()
                    .getTable(namespace + PORT_TABLE_SUFFIX), namespace);
        }

        @Override
        public KVPort next() {
            IKVEntry o = enumerator.next();
            KVPort e = KVPort.createFromKey(o.getKey(), namespace);
            e.deserialize(o.getValue(), o.getVersion());
            return e;
        }
    }

    /**
     * Gets the status.
     *
     * @return status
     */
    public STATUS getStatus() {
        return status;
    }

    /**
     * Sets the status.
     *
     * @param status new status
     */
    public void setStatus(final STATUS status) {
        this.status = status;
    }

    /**
     * Gets the DPID of the switch this port is on.
     *
     * @return DPID of the switch this port is on
     */
    public Long getDpid() {
        return dpid;
    }

    /**
     * Gets the port number of this port.
     *
     * @return port number of this port
     */
    public Long getNumber() {
        return number;
    }

    /**
     * Gets the PortID.
     *
     * @return PortID
     */
    public byte[] getId() {
        return getKey();
    }

    @Override
    public byte[] serialize() {
        Map<Object, Object> map = getPropertyMap();

        PortProperty.Builder port = PortProperty.newBuilder();
        port.setDpid(dpid);
        port.setNumber(number);
        port.setStatus(status.ordinal());

        if (!map.isEmpty()) {
            byte[] propMaps = serializePropertyMap(PORT_KRYO.get(), map);
            port.setValue(ByteString.copyFrom(propMaps));
        }

        return port.build().toByteArray();
    }

    @Override
    protected boolean deserialize(final byte[] bytes) {
        try {
            boolean success = true;

            PortProperty port = PortProperty.parseFrom(bytes);
            byte[] props = port.getValue().toByteArray();
            success &= deserializePropertyMap(PORT_KRYO.get(), props);
            this.status = STATUS.values()[port.getStatus()];

            return success;
        } catch (InvalidProtocolBufferException e) {
            log.error("Deserializing Port: " + this + " failed.", e);
            return false;
        }
    }

    @Override
    public String toString() {
        // TODO output all properties?
        return "[" + this.getClass().getSimpleName()
                + " 0x" + Long.toHexString(dpid) + "@" + number
                + " STATUS:" + status + "]";
    }
}
