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 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 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;
    }

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

    /**
     * Gets an instance from PortID in specified namespace.
     *
     * @param key PortID
     * @param namespace namespace to create this object.
     * @return {@link KVPort} instance
     * @note You need to call `read()` to get the DB content.
     */
    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 + "]";
    }
}
