package worker

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"time"
)

type report struct {
	avgTotal float64
	rps      float64

	results chan *result
	done    chan bool
	total   time.Duration

	numRes int64
	output string

	w io.Writer
}

func newReport(w io.Writer, results chan *result, output string, n int) *report {
	return &report{
		output:  output,
		results: results,
		done:    make(chan bool, 1),
		w:       w,
	}
}

func runReporter(r *report) {
	// Loop will continue until channel is closed
	for res := range r.results {
		r.numRes++
		r.avgTotal += res.duration.Seconds()
	}
	// Signal reporter is done.
	r.done <- true
}

func (r *report) finalize(total time.Duration) {
	r.total = total
	r.rps = float64(r.numRes) / r.total.Seconds()
	r.print()
}

func (r *report) print() {
	buf := &bytes.Buffer{}
	if err := newTemplate(r.output).Execute(buf, r.snapshot()); err != nil {
		log.Println("error:", err.Error())
		return
	}
	r.printf(buf.String())

	r.printf("\n")
}

func (r *report) printf(s string, v ...interface{}) {
	fmt.Fprintf(r.w, s, v...)
}

func (r *report) snapshot() Report {
	snapshot := Report{
		AvgTotal: r.avgTotal,
		Rps:      r.rps,
		Total:    r.total,
		NumRes:   r.numRes,
	}

	return snapshot
}

type Report struct {
	AvgTotal float64
	Rps      float64

	Total time.Duration

	NumRes int64
}

type LatencyDistribution struct {
	Percentage int
	Latency    float64
}

type Bucket struct {
	Mark      float64
	Count     int
	Frequency float64
}
