// Path: src/main/java/org/killbill/billing/plugin/meter/timeline/codec/SampleCoder.java
// public interface SampleCoder {
// 
//     public byte[] compressSamples(final List<ScalarSample> samples);
// 
//     public List<ScalarSample> decompressSamples(final byte[] sampleBytes) throws IOException;
// 
//     /**
//      * This method writes the binary encoding of the sample to the outputStream.  This encoding
//      * is the form saved in the db and scanned when read from the db.
//      *
//      * @param outputStream the stream to which bytes should be written
//      * @param sample       the sample to be written
//      */
//     public void encodeSample(final DataOutputStream outputStream, final SampleBase sample);
// 
//     /**
//      * Output the scalar value into the output stream
//      *
//      * @param outputStream the stream to which bytes should be written
//      * @param value        the sample value, interpreted according to the opcode
//      */
//     public void encodeScalarValue(final DataOutputStream outputStream, final SampleOpcode opcode, final Object value);
// 
//     /**
//      * This routine returns a ScalarSample that may have a smaller representation than the
//      * ScalarSample argument.  In particular, if tries hard to choose the most compact
//      * representation of double-precision values.
//      *
//      * @param sample A ScalarSample to be compressed
//      * @return Either the same ScalarSample is that input, for for some cases of opcode DOUBLE,
//      * a more compact ScalarSample which when processed returns a double value.
//      */
//     public ScalarSample compressSample(final ScalarSample sample);
// 
//     public Object decodeScalarValue(final DataInputStream inputStream, final SampleOpcode opcode) throws IOException;
// 
//     public double getMaxFractionError();
// 
//     public byte[] combineSampleBytes(final List<byte[]> sampleBytesList);
// 
//     public void scan(final TimelineChunk chunk, final SampleProcessor processor) throws IOException;
// 
//     public void scan(final byte[] samples, final byte[] times, final int sampleCount, final SampleProcessor processor) throws IOException;
// }
// 
// Path: src/main/java/org/killbill/billing/plugin/meter/timeline/persistent/TimelineDao.java
// public interface TimelineDao {
// 
//     // Sources table
// 
//     Integer getSourceId(String source, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     String getSource(Integer sourceId, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     BiMap<Integer, String> getSources(TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     int getOrAddSource(String source, CallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     // Event categories table
// 
//     Integer getEventCategoryId(String eventCategory, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     String getEventCategory(Integer eventCategoryId, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     BiMap<Integer, String> getEventCategories(TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     int getOrAddEventCategory(String eventCategory, CallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     // Metrics table
// 
//     Integer getMetricId(int eventCategory, String metric, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     CategoryRecordIdAndMetric getCategoryIdAndMetric(Integer metricId, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     BiMap<Integer, CategoryRecordIdAndMetric> getMetrics(TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     int getOrAddMetric(Integer eventCategoryId, String metric, CallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     // Timelines tables
// 
//     Long insertTimelineChunk(TimelineChunk timelineChunk, CallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     void getSamplesBySourceIdsAndMetricIds(List<Integer> sourceIds,
//                                            @Nullable List<Integer> metricIds,
//                                            DateTime startTime,
//                                            DateTime endTime,
//                                            TimelineChunkConsumer chunkConsumer,
//                                            TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     Integer insertLastStartTimes(StartTimes startTimes, CallContext context);
// 
//     StartTimes getLastStartTimes(TenantContext context);
// 
//     void deleteLastStartTimes(CallContext context);
// 
//     void bulkInsertTimelineChunks(List<TimelineChunk> timelineChunkList, CallContext context);
// 
//     void test(TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// }


import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.killbill.billing.plugin.meter.timeline.TimelineEventHandler;
import org.killbill.billing.plugin.meter.timeline.chunks.TimelineChunk;
import org.killbill.billing.plugin.meter.timeline.codec.DefaultSampleCoder;
import org.killbill.billing.plugin.meter.timeline.codec.SampleCoder;
import org.killbill.billing.plugin.meter.timeline.consumer.TimelineChunkConsumer;
import org.killbill.billing.plugin.meter.timeline.persistent.TimelineDao;
import org.killbill.billing.util.callcontext.TenantContext;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
/*
 * Copyright 2010-2014 Ning, Inc.
 * Copyright 2014 The Billing Project, LLC
 *
 * Ning licenses this file to you under the Apache License, version 2.0
 * (the "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package org.killbill.billing.plugin.meter.api.user;





public abstract class JsonSamplesOutputer {

    protected static final ObjectMapper objectMapper = new ObjectMapper();

    protected final TimelineEventHandler timelineEventHandler;
    protected final TimelineDao timelineDao;
// Path: src/main/java/org/killbill/billing/plugin/meter/timeline/codec/SampleCoder.java
// public interface SampleCoder {
// 
//     public byte[] compressSamples(final List<ScalarSample> samples);
// 
//     public List<ScalarSample> decompressSamples(final byte[] sampleBytes) throws IOException;
// 
//     /**
//      * This method writes the binary encoding of the sample to the outputStream.  This encoding
//      * is the form saved in the db and scanned when read from the db.
//      *
//      * @param outputStream the stream to which bytes should be written
//      * @param sample       the sample to be written
//      */
//     public void encodeSample(final DataOutputStream outputStream, final SampleBase sample);
// 
//     /**
//      * Output the scalar value into the output stream
//      *
//      * @param outputStream the stream to which bytes should be written
//      * @param value        the sample value, interpreted according to the opcode
//      */
//     public void encodeScalarValue(final DataOutputStream outputStream, final SampleOpcode opcode, final Object value);
// 
//     /**
//      * This routine returns a ScalarSample that may have a smaller representation than the
//      * ScalarSample argument.  In particular, if tries hard to choose the most compact
//      * representation of double-precision values.
//      *
//      * @param sample A ScalarSample to be compressed
//      * @return Either the same ScalarSample is that input, for for some cases of opcode DOUBLE,
//      * a more compact ScalarSample which when processed returns a double value.
//      */
//     public ScalarSample compressSample(final ScalarSample sample);
// 
//     public Object decodeScalarValue(final DataInputStream inputStream, final SampleOpcode opcode) throws IOException;
// 
//     public double getMaxFractionError();
// 
//     public byte[] combineSampleBytes(final List<byte[]> sampleBytesList);
// 
//     public void scan(final TimelineChunk chunk, final SampleProcessor processor) throws IOException;
// 
//     public void scan(final byte[] samples, final byte[] times, final int sampleCount, final SampleProcessor processor) throws IOException;
// }
// 
// Path: src/main/java/org/killbill/billing/plugin/meter/timeline/persistent/TimelineDao.java
// public interface TimelineDao {
// 
//     // Sources table
// 
//     Integer getSourceId(String source, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     String getSource(Integer sourceId, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     BiMap<Integer, String> getSources(TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     int getOrAddSource(String source, CallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     // Event categories table
// 
//     Integer getEventCategoryId(String eventCategory, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     String getEventCategory(Integer eventCategoryId, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     BiMap<Integer, String> getEventCategories(TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     int getOrAddEventCategory(String eventCategory, CallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     // Metrics table
// 
//     Integer getMetricId(int eventCategory, String metric, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     CategoryRecordIdAndMetric getCategoryIdAndMetric(Integer metricId, TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     BiMap<Integer, CategoryRecordIdAndMetric> getMetrics(TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     int getOrAddMetric(Integer eventCategoryId, String metric, CallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     // Timelines tables
// 
//     Long insertTimelineChunk(TimelineChunk timelineChunk, CallContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     void getSamplesBySourceIdsAndMetricIds(List<Integer> sourceIds,
//                                            @Nullable List<Integer> metricIds,
//                                            DateTime startTime,
//                                            DateTime endTime,
//                                            TimelineChunkConsumer chunkConsumer,
//                                            TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// 
//     Integer insertLastStartTimes(StartTimes startTimes, CallContext context);
// 
//     StartTimes getLastStartTimes(TenantContext context);
// 
//     void deleteLastStartTimes(CallContext context);
// 
//     void bulkInsertTimelineChunks(List<TimelineChunk> timelineChunkList, CallContext context);
// 
//     void test(TenantContext context) throws UnableToObtainConnectionException, CallbackFailedException;
// }


// Path: src/main/java/org/killbill/billing/plugin/meter/api/user/JsonSamplesOutputer.java
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.killbill.billing.plugin.meter.timeline.TimelineEventHandler;
import org.killbill.billing.plugin.meter.timeline.chunks.TimelineChunk;
import org.killbill.billing.plugin.meter.timeline.codec.DefaultSampleCoder;
import org.killbill.billing.plugin.meter.timeline.codec.SampleCoder;
import org.killbill.billing.plugin.meter.timeline.consumer.TimelineChunkConsumer;
import org.killbill.billing.plugin.meter.timeline.persistent.TimelineDao;
import org.killbill.billing.util.callcontext.TenantContext;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;

/*
 * Copyright 2010-2014 Ning, Inc.
 * Copyright 2014 The Billing Project, LLC
 *
 * Ning licenses this file to you under the Apache License, version 2.0
 * (the "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package org.killbill.billing.plugin.meter.api.user;





public abstract class JsonSamplesOutputer {

    protected static final ObjectMapper objectMapper = new ObjectMapper();

    protected final TimelineEventHandler timelineEventHandler;
    protected final TimelineDao timelineDao;
    protected final SampleCoder sampleCoder;