package net.onrc.onos.core.topology.web.serializers;

import net.onrc.onos.core.topology.DeviceEvent;
import net.onrc.onos.core.topology.LinkEvent;
import net.onrc.onos.core.topology.PortEvent;
import net.onrc.onos.core.topology.SwitchEvent;
import net.onrc.onos.core.topology.TopologyEvents;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.ser.std.SerializerBase;

import java.io.IOException;

/**
 * JSON serializer for TopologyEvents objects.  Used by WebSocket
 * implementation of the topology APIs.
 */
public class TopologyEventsSerializer extends SerializerBase<TopologyEvents> {

    /**
     * Default constructor. Performs basic initialization of the JSON
     * serializer.
     */
    public TopologyEventsSerializer() {
        super(TopologyEvents.class);
    }

    /**
     * Serialize a TopologyEvents object in JSON.  The resulting JSON contains
     * the added and removed topology objects: switches, links and ports.
     *
     * @param topologyEvents the TopologyEvents that is being converted to JSON
     * @param jsonGenerator generator to place the serialized JSON into
     * @param serializerProvider unused but required for method override
     * @throws IOException if the JSON serialization process fails
     */
    @Override
    public void serialize(TopologyEvents topologyEvents,
                          JsonGenerator jsonGenerator,
                          SerializerProvider serializerProvider)
            throws IOException {

        // Start the object
        jsonGenerator.writeStartObject();

        // Output the added switches array
        jsonGenerator.writeArrayFieldStart("addedSwitches");
        for (final SwitchEvent switchEvent : topologyEvents.getAddedSwitchEvents()) {
            jsonGenerator.writeObject(switchEvent);
        }
        jsonGenerator.writeEndArray();

        // Output the removed switches array
        jsonGenerator.writeArrayFieldStart("removedSwitches");
        for (final SwitchEvent switchEvent : topologyEvents.getRemovedSwitchEvents()) {
            jsonGenerator.writeObject(switchEvent);
        }
        jsonGenerator.writeEndArray();

        // Output the added ports array
        jsonGenerator.writeArrayFieldStart("addedPorts");
        for (final PortEvent portEvent : topologyEvents.getAddedPortEvents()) {
            jsonGenerator.writeObject(portEvent);
        }
        jsonGenerator.writeEndArray();

        // Output the removed ports array
        jsonGenerator.writeArrayFieldStart("removedPorts");
        for (final PortEvent portEvent : topologyEvents.getRemovedPortEvents()) {
            jsonGenerator.writeObject(portEvent);
        }
        jsonGenerator.writeEndArray();

        // Output the added links array
        jsonGenerator.writeArrayFieldStart("addedLinks");
        for (final LinkEvent linkEvent : topologyEvents.getAddedLinkEvents()) {
            jsonGenerator.writeObject(linkEvent);
        }
        jsonGenerator.writeEndArray();

        // Output the removed links array
        jsonGenerator.writeArrayFieldStart("removedLinks");
        for (final LinkEvent linkEvent : topologyEvents.getRemovedLinkEvents()) {
            jsonGenerator.writeObject(linkEvent);
        }
        jsonGenerator.writeEndArray();

        // Output the added hosts array
        jsonGenerator.writeArrayFieldStart("addedHosts");
        for (final DeviceEvent hostEvent : topologyEvents.getAddedHostEvents()) {
            jsonGenerator.writeObject(hostEvent);
        }
        jsonGenerator.writeEndArray();

        // Output the removed hosts array
        jsonGenerator.writeArrayFieldStart("removedHosts");
        for (final DeviceEvent hostEvent : topologyEvents.getRemovedHostEvents()) {
            jsonGenerator.writeObject(hostEvent);
        }
        jsonGenerator.writeEndArray();

        // All done
        jsonGenerator.writeEndObject();
    }
}
