/*
 * Author: Radovan Cerveny
 */

#include <sstream>
#include "../MeasurementFrame.hpp"
#include <iostream>

using namespace std::chrono;

namespace measurements {

void TimeDataFrame::init ( unsigned frameIdx, measurements::stealth_vector < MeasurementFrame > & frames ) {
	MeasurementFrame & currentFrame = frames[frameIdx];

	currentFrame.time.start = high_resolution_clock::now ( );
}

void TimeDataFrame::update ( unsigned frameIdx, measurements::stealth_vector < MeasurementFrame > & frames ) {
	MeasurementFrame & currentFrame = frames[frameIdx];

	currentFrame.time.duration = duration_cast < microseconds > ( high_resolution_clock::now ( ) - currentFrame.time.start );
	currentFrame.time.inFrameDuration += currentFrame.time.duration;

	MeasurementFrame & parentFrame = frames[currentFrame.parentIdx];

	parentFrame.time.inFrameDuration -= currentFrame.time.duration;
}

TimeDataFrame TimeDataFrame::aggregate ( const std::vector < MeasurementFrame > & framesToAggregate ) {
	TimeDataFrame aggregatedTimeDataFrame = TimeDataFrame ( );

	 // we want to compute simple average of times
	for ( const MeasurementFrame & frame : framesToAggregate ) {
		aggregatedTimeDataFrame.duration += frame.time.duration;
		aggregatedTimeDataFrame.inFrameDuration += frame.time.inFrameDuration;
	}

	aggregatedTimeDataFrame.duration /= framesToAggregate.size ( );
	aggregatedTimeDataFrame.inFrameDuration /= framesToAggregate.size ( );

	return aggregatedTimeDataFrame;
}

std::ostream & operator <<( std::ostream & os, const TimeDataFrame & tdf ) {
	os << tdf.duration << " dur, " << tdf.inFrameDuration << " if_dur";
	return os;
}

std::ostream & operator <<( std::ostream & os, const std::chrono::microseconds & ms ) {
	os << ms.count ( ) << "ms";
	return os;
}

}
