/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) Module
 * -----------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed 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.
 *
 *//*!
 * \file
 * \brief Calibration tools.
 *//*--------------------------------------------------------------------*/

#include "glsCalibration.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "deStringUtil.hpp"
#include "deMath.h"
#include "deClock.h"

#include <algorithm>
#include <limits>

using std::string;
using std::vector;
using tcu::Vec2;
using tcu::TestLog;
using tcu::TestNode;
using namespace glu;

namespace deqp
{
namespace gls
{

// Reorders input arbitrarily, linear complexity and no allocations
template<typename T>
float destructiveMedian (vector<T>& data)
{
	const typename vector<T>::iterator mid = data.begin()+data.size()/2;

	std::nth_element(data.begin(), mid, data.end());

	if (data.size()%2 == 0) // Even number of elements, need average of two centermost elements
		return (*mid + *std::max_element(data.begin(), mid))*0.5f; // Data is partially sorted around mid, mid is half an item after center
	else
		return *mid;
}

LineParameters theilSenLinearRegression (const std::vector<tcu::Vec2>& dataPoints)
{
	const float		epsilon					= 1e-6f;

	const int		numDataPoints			= (int)dataPoints.size();
	vector<float>	pairwiseCoefficients;
	vector<float>	pointwiseOffsets;
	LineParameters	result					(0.0f, 0.0f);

	// Compute the pairwise coefficients.
	for (int i = 0; i < numDataPoints; i++)
	{
		const Vec2& ptA = dataPoints[i];

		for (int j = 0; j < i; j++)
		{
			const Vec2& ptB = dataPoints[j];

			if (de::abs(ptA.x() - ptB.x()) > epsilon)
				pairwiseCoefficients.push_back((ptA.y() - ptB.y()) / (ptA.x() - ptB.x()));
		}
	}

	// Find the median of the pairwise coefficients.
	// \note If there are no data point pairs with differing x values, the coefficient variable will stay zero as initialized.
	if (!pairwiseCoefficients.empty())
		result.coefficient = destructiveMedian(pairwiseCoefficients);

	// Compute the offsets corresponding to the median coefficient, for all data points.
	for (int i = 0; i < numDataPoints; i++)
		pointwiseOffsets.push_back(dataPoints[i].y() - result.coefficient*dataPoints[i].x());

	// Find the median of the offsets.
	// \note If there are no data points, the offset variable will stay zero as initialized.
	if (!pointwiseOffsets.empty())
		result.offset = destructiveMedian(pointwiseOffsets);

	return result;
}

// Sample from given values using linear interpolation at a given position as if values were laid to range [0, 1]
template <typename T>
static float linearSample (const std::vector<T>& values, float position)
{
	DE_ASSERT(position >= 0.0f);
	DE_ASSERT(position <= 1.0f);

	const int	maxNdx				= (int)values.size() - 1;
	const float	floatNdx			= (float)maxNdx * position;
	const int	lowerNdx			= (int)deFloatFloor(floatNdx);
	const int	higherNdx			= lowerNdx + (lowerNdx == maxNdx ? 0 : 1); // Use only last element if position is 1.0
	const float	interpolationFactor = floatNdx - (float)lowerNdx;

	DE_ASSERT(lowerNdx >= 0 && lowerNdx < (int)values.size());
	DE_ASSERT(higherNdx >= 0 && higherNdx < (int)values.size());
	DE_ASSERT(interpolationFactor >= 0 && interpolationFactor < 1.0f);

	return tcu::mix((float)values[lowerNdx], (float)values[higherNdx], interpolationFactor);
}

LineParametersWithConfidence theilSenSiegelLinearRegression (const std::vector<tcu::Vec2>& dataPoints, float reportedConfidence)
{
	DE_ASSERT(!dataPoints.empty());

	// Siegel's variation

	const float						epsilon				= 1e-6f;
	const int						numDataPoints		= (int)dataPoints.size();
	std::vector<float>				medianSlopes;
	std::vector<float>				pointwiseOffsets;
	LineParametersWithConfidence	result;

	// Compute the median slope via each element
	for (int i = 0; i < numDataPoints; i++)
	{
		const tcu::Vec2&	ptA		= dataPoints[i];
		std::vector<float>	slopes;

		slopes.reserve(numDataPoints);

		for (int j = 0; j < numDataPoints; j++)
		{
			const tcu::Vec2& ptB = dataPoints[j];

			if (de::abs(ptA.x() - ptB.x()) > epsilon)
				slopes.push_back((ptA.y() - ptB.y()) / (ptA.x() - ptB.x()));
		}

		// Add median of slopes through point i
		medianSlopes.push_back(destructiveMedian(slopes));
	}

	DE_ASSERT(!medianSlopes.empty());

	// Find the median of the pairwise coefficients.
	std::sort(medianSlopes.begin(), medianSlopes.end());
	result.coefficient = linearSample(medianSlopes, 0.5f);

	// Compute the offsets corresponding to the median coefficient, for all data points.
	for (int i = 0; i < numDataPoints; i++)
		pointwiseOffsets.push_back(dataPoints[i].y() - result.coefficient*dataPoints[i].x());

	// Find the median of the offsets.
	std::sort(pointwiseOffsets.begin(), pointwiseOffsets.end());
	result.offset = linearSample(pointwiseOffsets, 0.5f);

	// calculate confidence intervals
	result.coefficientConfidenceLower = linearSample(medianSlopes, 0.5f - reportedConfidence*0.5f);
	result.coefficientConfidenceUpper = linearSample(medianSlopes, 0.5f + reportedConfidence*0.5f);

	result.offsetConfidenceLower = linearSample(pointwiseOffsets, 0.5f - reportedConfidence*0.5f);
	result.offsetConfidenceUpper = linearSample(pointwiseOffsets, 0.5f + reportedConfidence*0.5f);

	result.confidence = reportedConfidence;

	return result;
}

bool MeasureState::isDone (void) const
{
	return (int)frameTimes.size() >= maxNumFrames || (frameTimes.size() >= 2 &&
													  frameTimes[frameTimes.size()-2] >= (deUint64)frameShortcutTime &&
													  frameTimes[frameTimes.size()-1] >= (deUint64)frameShortcutTime);
}

deUint64 MeasureState::getTotalTime (void) const
{
	deUint64 time = 0;
	for (int i = 0; i < (int)frameTimes.size(); i++)
		time += frameTimes[i];
	return time;
}

void MeasureState::clear (void)
{
	maxNumFrames		= 0;
	frameShortcutTime	= std::numeric_limits<float>::infinity();
	numDrawCalls		= 0;
	frameTimes.clear();
}

void MeasureState::start (int maxNumFrames_, float frameShortcutTime_, int numDrawCalls_)
{
	frameTimes.clear();
	frameTimes.reserve(maxNumFrames_);
	maxNumFrames		= maxNumFrames_;
	frameShortcutTime	= frameShortcutTime_;
	numDrawCalls		= numDrawCalls_;
}

TheilSenCalibrator::TheilSenCalibrator (void)
	: m_params	(1 /* initial calls */, 10 /* calibrate iter frames */, 2000.0f /* calibrate iter shortcut threshold */, 31 /* max calibration iterations */,
				 1000.0f/30.0f /* target frame time */, 1000.0f/60.0f /* frame time cap */, 1000.0f /* target measure duration */)
	, m_state	(INTERNALSTATE_LAST)
{
	clear();
}

TheilSenCalibrator::TheilSenCalibrator (const CalibratorParameters& params)
	: m_params	(params)
	, m_state	(INTERNALSTATE_LAST)
{
	clear();
}

TheilSenCalibrator::~TheilSenCalibrator()
{
}

void TheilSenCalibrator::clear (void)
{
	m_measureState.clear();
	m_calibrateIterations.clear();
	m_state = INTERNALSTATE_CALIBRATING;
}

void TheilSenCalibrator::clear (const CalibratorParameters& params)
{
	m_params = params;
	clear();
}

TheilSenCalibrator::State TheilSenCalibrator::getState (void) const
{
	if (m_state == INTERNALSTATE_FINISHED)
		return STATE_FINISHED;
	else
	{
		DE_ASSERT(m_state == INTERNALSTATE_CALIBRATING || !m_measureState.isDone());
		return m_measureState.isDone() ? STATE_RECOMPUTE_PARAMS : STATE_MEASURE;
	}
}

void TheilSenCalibrator::recordIteration (deUint64 iterationTime)
{
	DE_ASSERT((m_state == INTERNALSTATE_CALIBRATING || m_state == INTERNALSTATE_RUNNING) && !m_measureState.isDone());
	m_measureState.frameTimes.push_back(iterationTime);

	if (m_state == INTERNALSTATE_RUNNING && m_measureState.isDone())
		m_state = INTERNALSTATE_FINISHED;
}

void TheilSenCalibrator::recomputeParameters (void)
{
	DE_ASSERT(m_state == INTERNALSTATE_CALIBRATING);
	DE_ASSERT(m_measureState.isDone());

	// Minimum and maximum acceptable frame times.
	const float		minGoodFrameTimeUs	= m_params.targetFrameTimeUs * 0.95f;
	const float		maxGoodFrameTimeUs	= m_params.targetFrameTimeUs * 1.15f;

	const int		numIterations		= (int)m_calibrateIterations.size();

	// Record frame time.
	if (numIterations > 0)
	{
		m_calibrateIterations.back().frameTime = (float)((double)m_measureState.getTotalTime() / (double)m_measureState.frameTimes.size());

		// Check if we're good enough to stop calibrating.
		{
			bool endCalibration = false;

			// Is the maximum calibration iteration limit reached?
			endCalibration = endCalibration || (int)m_calibrateIterations.size() >= m_params.maxCalibrateIterations;

			// Do a few past iterations have frame time in acceptable range?
			{
				const int numRelevantPastIterations = 2;

				if (!endCalibration && (int)m_calibrateIterations.size() >= numRelevantPastIterations)
				{
					const CalibrateIteration* const		past			= &m_calibrateIterations[m_calibrateIterations.size() - numRelevantPastIterations];
					bool								allInGoodRange	= true;

					for (int i = 0; i < numRelevantPastIterations && allInGoodRange; i++)
					{
						const float frameTimeUs = past[i].frameTime;
						if (!de::inRange(frameTimeUs, minGoodFrameTimeUs, maxGoodFrameTimeUs))
							allInGoodRange = false;
					}

					endCalibration = endCalibration || allInGoodRange;
				}
			}

			// Do a few past iterations have similar-enough call counts?
			{
				const int numRelevantPastIterations = 3;
				if (!endCalibration && (int)m_calibrateIterations.size() >= numRelevantPastIterations)
				{
					const CalibrateIteration* const		past			= &m_calibrateIterations[m_calibrateIterations.size() - numRelevantPastIterations];
					int									minCallCount	= std::numeric_limits<int>::max();
					int									maxCallCount	= std::numeric_limits<int>::min();

					for (int i = 0; i < numRelevantPastIterations; i++)
					{
						minCallCount = de::min(minCallCount, past[i].numDrawCalls);
						maxCallCount = de::max(maxCallCount, past[i].numDrawCalls);
					}

					if ((float)(maxCallCount - minCallCount) <= (float)minCallCount * 0.1f)
						endCalibration = true;
				}
			}

			// Is call count just 1, and frame time still way too high?
			endCalibration = endCalibration || (m_calibrateIterations.back().numDrawCalls == 1 && m_calibrateIterations.back().frameTime > m_params.targetFrameTimeUs*2.0f);

			if (endCalibration)
			{
				const int	minFrames			= 10;
				const int	maxFrames			= 60;
				int			numMeasureFrames	= deClamp32(deRoundFloatToInt32(m_params.targetMeasureDurationUs / m_calibrateIterations.back().frameTime), minFrames, maxFrames);

				m_state = INTERNALSTATE_RUNNING;
				m_measureState.start(numMeasureFrames, m_params.calibrateIterationShortcutThreshold, m_calibrateIterations.back().numDrawCalls);
				return;
			}
		}
	}

	DE_ASSERT(m_state == INTERNALSTATE_CALIBRATING);

	// Estimate new call count.
	{
		int newCallCount;

		if (numIterations == 0)
			newCallCount = m_params.numInitialCalls;
		else
		{
			vector<Vec2> dataPoints;
			for (int i = 0; i < numIterations; i++)
			{
				if (m_calibrateIterations[i].numDrawCalls == 1 || m_calibrateIterations[i].frameTime > m_params.frameTimeCapUs*1.05f) // Only account for measurements not too near the cap.
					dataPoints.push_back(Vec2((float)m_calibrateIterations[i].numDrawCalls, m_calibrateIterations[i].frameTime));
			}

			if (numIterations == 1)
				dataPoints.push_back(Vec2(0.0f, 0.0f)); // If there's just one measurement so far, this will help in getting the next estimate.

			{
				const float				targetFrameTimeUs	= m_params.targetFrameTimeUs;
				const float				coeffEpsilon		= 0.001f; // Coefficient must be large enough (and positive) to be considered sensible.

				const LineParameters	estimatorLine		= theilSenLinearRegression(dataPoints);

				int						prevMaxCalls		= 0;

				// Find the maximum of the past call counts.
				for (int i = 0; i < numIterations; i++)
					prevMaxCalls = de::max(prevMaxCalls, m_calibrateIterations[i].numDrawCalls);

				if (estimatorLine.coefficient < coeffEpsilon) // Coefficient not good for sensible estimation; increase call count enough to get a reasonably different value.
					newCallCount = 2*prevMaxCalls;
				else
				{
					// Solve newCallCount such that approximately targetFrameTime = offset + coefficient*newCallCount.
					newCallCount = (int)((targetFrameTimeUs - estimatorLine.offset) / estimatorLine.coefficient + 0.5f);

					// We should generally prefer FPS counts below the target rather than above (i.e. higher frame times rather than lower).
					if (estimatorLine.offset + estimatorLine.coefficient*(float)newCallCount < minGoodFrameTimeUs)
						newCallCount++;
				}

				// Make sure we have at least minimum amount of calls, and don't allow increasing call count too much in one iteration.
				newCallCount = de::clamp(newCallCount, 1, prevMaxCalls*10);
			}
		}

		m_measureState.start(m_params.maxCalibrateIterationFrames, m_params.calibrateIterationShortcutThreshold, newCallCount);
		m_calibrateIterations.push_back(CalibrateIteration(newCallCount, 0.0f));
	}
}

void logCalibrationInfo (tcu::TestLog& log, const TheilSenCalibrator& calibrator)
{
	const CalibratorParameters&				params				= calibrator.getParameters();
	const std::vector<CalibrateIteration>&	calibrateIterations	= calibrator.getCalibrationInfo();

	// Write out default calibration info.

	log << TestLog::Section("CalibrationInfo", "Calibration Info")
		<< TestLog::Message  << "Target frame time: " << params.targetFrameTimeUs << " us (" << 1000000 / params.targetFrameTimeUs << " fps)" << TestLog::EndMessage;

	for (int iterNdx = 0; iterNdx < (int)calibrateIterations.size(); iterNdx++)
	{
		log << TestLog::Message << "  iteration " << iterNdx << ": " << calibrateIterations[iterNdx].numDrawCalls << " calls => "
								<< de::floatToString(calibrateIterations[iterNdx].frameTime, 2) << " us ("
								<< de::floatToString(1000000.0f / calibrateIterations[iterNdx].frameTime, 2) << " fps)" << TestLog::EndMessage;
	}
	log << TestLog::Integer("CallCount",	"Calibrated call count",	"",	QP_KEY_TAG_NONE, calibrator.getMeasureState().numDrawCalls)
		<< TestLog::Integer("FrameCount",	"Calibrated frame count",	"", QP_KEY_TAG_NONE, (int)calibrator.getMeasureState().frameTimes.size());
	log << TestLog::EndSection;
}

} // gls
} // deqp
