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.PortData;
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 PortData.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 PortData.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(), 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 + "]";
    }
}
