package swift.proto;

import java.io.PrintStream;

import sys.net.impl.KryoLib;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.io.UnsafeMemoryOutput;

/**
 * A collector of metadata statistics.
 * 
 * @author mzawirski
 */
public class MetadataStatsCollectorImpl implements MetadataStatsCollector {
    private String scoutId;
    private ThreadLocal<UnsafeMemoryOutput> freshKryoBuffer = new ThreadLocal<UnsafeMemoryOutput>() {
        protected UnsafeMemoryOutput initialValue() {
            return new UnsafeMemoryOutput(1 << 20);
        }
    };
    private PrintStream stream;

    /**
     * Creates a collector.
     * 
     * @param enabled
     *            true if the collection is active
     */
    public MetadataStatsCollectorImpl(final String scoutId, PrintStream stream) {
        this.scoutId = scoutId;
        this.stream = stream;
        this.stream.println("; metadata stats format: <session_id>,METADATA_<message_name>,"
                + "<total_message_size>,<version_or_update_size>,<value_size>,<max_vv_exceptions_num>");
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public Output getFreshKryoBuffer() {
        Output buffer = freshKryoBuffer.get();
        buffer.clear();
        return buffer;
    }

    @Override
    public Kryo getFreshKryo() {
        final Kryo kryo = KryoLib.kryoWithoutAutoreset();
        kryo.reset();
        return kryo;
    }

    @Override
    public void recordStats(Object message, int totalSize, int objectOrUpdateSize, int objectOrUpdateValueSize,
            int maxExceptionsNum) {
        // TODO: we should intercept totalSize at the serialization time rather
        // than forcing re-serialization for measurements purposes
        if (isEnabled()) {
            stream.printf("%s,METADATA_%s,%d,%d,%d,%d\n", scoutId, message.getClass().getSimpleName(), totalSize,
                    objectOrUpdateSize, objectOrUpdateValueSize, maxExceptionsNum);
        }
    }
}

@@ -984,16 +984,31 @@
 ion_id%3E,
+%3Ctimestamp_ms%3E,
 METADATA
@@ -1889,16 +1889,19 @@
 ntf(%22%25s,
+%25s,
 METADATA
@@ -1933,26 +1933,75 @@
 Id, 
-message.getClass()
+System.currentTimeMillis(), message.getClass()%0A                    
 .get
@@ -2024,36 +2024,16 @@
 talSize,
-%0A                   
  objectO

add timestamps to metadata measurements