#include "PulseLengthStatAnalyzerResults.h"
#include <AnalyzerHelpers.h>
#include "PulseLengthStatAnalyzer.h"
#include "PulseLengthStatAnalyzerSettings.h"
#include <cstdio>
#include <fstream>

PulseLengthStatAnalyzerResults::PulseLengthStatAnalyzerResults(PulseLengthStatAnalyzer* analyzer,
															   PulseLengthStatAnalyzerSettings* settings)
	: AnalyzerResults(),
	  mSettings(settings),
	  mAnalyzer(analyzer)
{
}

PulseLengthStatAnalyzerResults::~PulseLengthStatAnalyzerResults()
{
}

static void FormatDurationUs(U64 duration_samples, U32 sample_rate_hz, char* out, size_t out_sz)
{
	if (sample_rate_hz == 0)
	{
		snprintf(out, out_sz, "? us");
		return;
	}
	const double us = double(duration_samples) * 1e6 / double(sample_rate_hz);
	snprintf(out, out_sz, "%.2f us", us);
}

void PulseLengthStatAnalyzerResults::GenerateBubbleText(U64 frame_index, Channel& channel, DisplayBase display_base)
{
	(void)display_base;
	ClearResultStrings();
	Frame frame = GetFrame(frame_index);

	const U32 fs = mAnalyzer->GetSampleRate();
	char dur[64];
	FormatDurationUs(frame.mData1, fs, dur, sizeof dur);

	const char* lev = (frame.mFlags != 0) ? "HIGH" : "LOW";
	char line[160];
	snprintf(line, sizeof line, "%s %s", lev, dur);
	AddResultString(line);
}

void PulseLengthStatAnalyzerResults::GenerateExportFile(const char* file, DisplayBase display_base, U32 export_type_user_id)
{
	(void)export_type_user_id;
	(void)display_base;
	std::ofstream file_stream(file, std::ios::out);

	const U64 trigger_sample = mAnalyzer->GetTriggerSample();
	const U32 sample_rate = mAnalyzer->GetSampleRate();

	file_stream << "Time [s],Level,Duration_samples,Duration_us" << std::endl;

	const U64 num_frames = GetNumFrames();
	for (U32 i = 0; i < num_frames; i++)
	{
		Frame frame = GetFrame(i);

		char time_str[128];
		AnalyzerHelpers::GetTimeString(frame.mStartingSampleInclusive, trigger_sample, sample_rate, time_str, 128);

		char dur_us[64];
		FormatDurationUs(frame.mData1, sample_rate, dur_us, sizeof dur_us);

		file_stream << time_str << "," << ((frame.mFlags != 0) ? "HIGH" : "LOW") << "," << frame.mData1 << ","
					<< dur_us << std::endl;

		if (UpdateExportProgressAndCheckForCancel(i, num_frames) == true)
		{
			file_stream.close();
			return;
		}
	}

	file_stream.close();
}

void PulseLengthStatAnalyzerResults::GenerateFrameTabularText(U64 frame_index, DisplayBase display_base)
{
#ifdef SUPPORTS_PROTOCOL_SEARCH
	(void)display_base;
	Frame frame = GetFrame(frame_index);
	ClearTabularText();

	const U32 fs = mAnalyzer->GetSampleRate();
	char dur[64];
	FormatDurationUs(frame.mData1, fs, dur, sizeof dur);
	AddTabularText((frame.mFlags != 0) ? "H" : "L");
	AddTabularText(dur);
#endif
}

void PulseLengthStatAnalyzerResults::GeneratePacketTabularText(U64 packet_id, DisplayBase display_base)
{
	(void)packet_id;
	(void)display_base;
}

void PulseLengthStatAnalyzerResults::GenerateTransactionTabularText(U64 transaction_id, DisplayBase display_base)
{
	(void)transaction_id;
	(void)display_base;
}
