#!/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.
#

from __future__ import print_function
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()
