package telemetry

import (
	logging "code.justin.tv/amzn/TwitchLogging"
	"log"
	"time"
)

// SampleReporter combines a builder and observer to make reporting metrics easier.  Validation errors are logged.
type SampleReporter struct {
	SampleBuilder
	SampleObserver
	Logger logging.Logger
}

// Report builds a new sample using SampleBuilder.Build and sends it to the observer.
func (reporter *SampleReporter) Report(metricName string, value float64, units string) {
	sample, err := reporter.SampleBuilder.Build(metricName, value, units)
	if err == nil {
		reporter.SampleObserver.ObserveSample(sample)
	} else {
		if reporter.Logger != nil {
			reporter.Logger.Log("Failed to report sample", "err", err.Error())
		} else {
			log.Printf("Failed to report sample: %v", err)
		}
	}
}

// ReportDurationSample builds a new sample using SampleBuilder.BuildDurationSample and sends it to the observer.
func (reporter *SampleReporter) ReportDurationSample(metricName string, duration time.Duration) {
	sample, err := reporter.SampleBuilder.BuildDurationSample(metricName, duration)
	if err == nil {
		reporter.SampleObserver.ObserveSample(sample)
	} else {
		if reporter.Logger != nil {
			reporter.Logger.Log("Failed to report duration sample", "err", err.Error())
		} else {
			log.Printf("Failed to report duration sample: %v", err)
		}
	}
}

// ReportAvailabilitySamples builds samples using SampleBuilder.BuildAvailabilitySamples and sends them to the observer.
func (reporter *SampleReporter) ReportAvailabilitySamples(availability AvailabilityCode) {
	samples, err := reporter.SampleBuilder.BuildAvailabilitySamples(availability)
	if err == nil {
		for _, sample := range samples {
			reporter.SampleObserver.ObserveSample(sample)
		}
	} else {
		if reporter.Logger != nil {
			reporter.Logger.Log("Failed to report availability samples", "err", err.Error())
		} else {
			log.Printf("Failed to report availability samples: %v", err)
		}
	}
}
