#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF 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.
#

import time

TS = "ts"
TIME_SEC = 1000000000
MILLISECOND = 1000

class Statistic:
    def message(self, msg):
        return
    def report(self):
        return ""
    def header(self):
        return ""


class Throughput(Statistic):
    def __init__(self):
        self.messages = 0
        self.started = False

    def message(self, m):
        self.messages += 1
        if not self.started:
            self.start = time.time()
            self.started = True

    def header(self):
        return "tp(m/s)"

    def report(self):
	if self.started:
            elapsed = time.time() - self.start
            return str(int(self.messages/elapsed))
	else:
	    return "0"


class ThroughputAndLatency(Throughput):
    def __init__(self):
	Throughput.__init__(self)
        self.total = 0.0
        self.min = float('inf')
        self.max = -float('inf')
        self.samples = 0

    def message(self, m):
        Throughput.message(self, m)
        if TS in m.properties:
            self.samples+=1
            latency = MILLISECOND * (time.time() - float(m.properties[TS])/TIME_SEC)
            if latency > 0:
                self.total += latency
                if latency < self.min:
                    self.min = latency
                if latency > self.max:
                    self.max = latency

    def header(self):
#        Throughput.header(self)
        return "%s\tl-min\tl-max\tl-avg" % Throughput.header(self)

    def report(self):
        output = Throughput.report(self)
        if (self.samples > 0):
	    output += "\t%.2f\t%.2f\t%.2f" %(self.min, self.max, self.total/self.samples)
	return output


# Report batch and overall statistics
class ReporterBase:
    def __init__(self, batch, wantHeader):
        self.batchSize = batch
        self.batchCount = 0
        self.headerPrinted = not wantHeader
        self.overall = None
        self.batch = None

    def create(self):
        return

    # Count message in the statistics
    def message(self, m):
        if self.overall == None:
            self.overall = self.create()
        self.overall.message(m)
        if self.batchSize:
            if self.batch == None:
                self.batch = self.create()
            self.batch.message(m)
            self.batchCount+=1
            if self.batchCount == self.batchSize:
                self.header()
                print self.batch.report()
                self.create()
                self.batchCount = 0

    # Print overall report.
    def report(self):
        if self.overall == None:
            self.overall = self.create()
        self.header()
        print self.overall.report()

    def header(self):
        if not self.headerPrinted:
            if self.overall == None:
                self.overall = self.create()
            print self.overall.header()
            self.headerPrinted = True


class Reporter(ReporterBase):
    def __init__(self, batchSize, wantHeader, Stats):
        ReporterBase.__init__(self, batchSize, wantHeader)
        self.__stats = Stats

    def create(self):
        ClassName = self.__stats.__class__
        return ClassName()
