// Copyright (c) 2020 Metrolab Technology S.A., Geneva, Switzerland (www.metrolab.com)
// See the included file LICENSE.txt for the licensing conditions.

//////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Test THM1176 API: CalibrateZeroOffset, RestoreZeroOffset, Reset, SwitchToDFUMode

#include "gtest/gtest.h"
#include "THM1176TestUtilities.h"
#include <ctime>

using namespace MTL::Instrument;
using namespace MTL::Instrument::THM1176Types;

/// \brief Test THM1176 API: CalibrateZeroOffset, RestoreZeroOffset, Reset, SwitchToDFUMode
class CTHM1176MiscUtilitiesTest : public ::testing::Test
{
protected:
	static THM1176_TEST_RESOURCE_MANAGER_CLASS * pResourceManager;
	static CTHM1176Instrument<THM1176_TEST_INSTRUMENT_CLASS, THM1176_TEST_RESOURCE_MANAGER_CLASS> * pTHM1176;

	static void SetUpTestCase()
	{
		ASSERT_EQ(true, ConnectToTHM1176(pResourceManager, pTHM1176));
		ASSERT_NE(nullptr, pResourceManager);
		ASSERT_NE(nullptr, pTHM1176);
		ASSERT_EQ(true, pTHM1176->IsOpen());
		ASSERT_EQ(true, pTHM1176->Reset());
	}
	
	static void TearDownTestCase()
	{
		delete pTHM1176;
		pTHM1176 = nullptr;
		delete pResourceManager;
		pResourceManager = nullptr;
	}
	
	virtual void SetUp()
	{
		// Reset the instruent.
		ASSERT_NE(pTHM1176, nullptr);
		ASSERT_EQ(true, pTHM1176->Reset());
	}
};
THM1176_TEST_RESOURCE_MANAGER_CLASS * CTHM1176MiscUtilitiesTest::pResourceManager = nullptr;
CTHM1176Instrument<THM1176_TEST_INSTRUMENT_CLASS, THM1176_TEST_RESOURCE_MANAGER_CLASS> * CTHM1176MiscUtilitiesTest::pTHM1176 = nullptr;

/// \test Test CalibrateZeroOffset and RestoreZeroOffset methods.
TEST_F(CTHM1176MiscUtilitiesTest, ZeroOffset)
{
    // Get the settings before the calibration.
    std::string l_Command = ":CALC:AVER:COUN?;:CAL:STAT?;:FORM:DATA?;:INIT:CONT?;:SENS?;AUTO?;:TRIG:COUN?;SOUR?;TIM?;:UNIT?";
    CSCPIBuffer l_SettingsBefore;
    ASSERT_EQ(true, pTHM1176->WriteAndRead(l_Command, l_SettingsBefore));

	// Calibrate the zero offset.
    ASSERT_EQ(true, pTHM1176->CalibrateZeroOffset(true));

    // Check to make sure that all the settings are the same.
    CSCPIBuffer l_SettingsAfter;
    ASSERT_EQ(true, pTHM1176->WriteAndRead(l_Command, l_SettingsAfter));
    EXPECT_EQ(std::string(l_SettingsBefore.begin(), l_SettingsBefore.end()), std::string(l_SettingsAfter.begin(), l_SettingsAfter.end()));

    // Make sure we get an error if we're calibrating a TFM1186, not otherwise.
    sIdentifier l_ID;
    ASSERT_EQ(true, pTHM1176->GetIdentification(l_ID));
    ASSERT_EQ(l_ID.Model != "TFM1186", pTHM1176->CalibrateZeroOffset());

	// Restore the zero offset.
	ASSERT_EQ(true, pTHM1176->RestoreZeroOffset());
	}

/// \test Test Reset method.
TEST_F(CTHM1176MiscUtilitiesTest, Reset)
{
	// Set the THM1176 to a non-standard configuration.
	CUnitsList l_AllUnits;
	ASSERT_EQ(true, pTHM1176->GetAllUnits(l_AllUnits));
	ASSERT_EQ(true, pTHM1176->ParmUnitsSet(l_AllUnits.back()));

	sRange<sBoundedParm> l_RangeBounds;
	ASSERT_EQ(true, pTHM1176->ParmRangeGet(l_RangeBounds));
	sRange<uParm> l_Range;
	l_Range.Auto = false;
	l_Range.Range = l_RangeBounds.Range.Min;
	ASSERT_EQ(true, pTHM1176->ParmRangeSet(l_Range));
	
	sAveraging<sBoundedParm> l_AvgBounds;
	ASSERT_EQ(true, pTHM1176->ParmAveragingGet(l_AvgBounds));
	sAveraging<uParm> l_Avg;
	l_Avg.NoPoints = l_AvgBounds.NoPoints.Max;
	ASSERT_EQ(true, pTHM1176->ParmAveragingSet(l_Avg));
	
	sInputTrigger<sBoundedParm> l_TrigBounds;
	ASSERT_EQ(true, pTHM1176->ParmTriggerInputGet(l_TrigBounds));
	sInputTrigger<uParm> l_Trig;
	l_Trig.Source	= kInputTrigSrcTimer;
	l_Trig.Count		= l_TrigBounds.Count.Max;
	l_Trig.Period_s	= l_TrigBounds.Period_s.Min;
	ASSERT_EQ(true, pTHM1176->ParmTriggerInputSet(l_Trig));
	
	bool l_Sleep = true;
	ASSERT_EQ(true, pTHM1176->ParmSleepSet(l_Sleep));
	
	bool l_UseCal = false;
	ASSERT_EQ(true, pTHM1176->ParmUseCalibrationSet(l_UseCal));
	
	// Reset the THM1176.
	ASSERT_EQ(true, pTHM1176->Reset());
	
	// Check the settings.
	eUnits l_Units;
	ASSERT_EQ(true, pTHM1176->ParmUnitsGet(l_Units));
	EXPECT_EQ(kT, l_Units);
	
	ASSERT_EQ(true, pTHM1176->ParmRangeGet(l_Range));
	EXPECT_EQ(true, l_Range.Auto);
	EXPECT_EQ(l_RangeBounds.Range.Max, l_Range.Range);
	
	ASSERT_EQ(true, pTHM1176->ParmAveragingGet(l_Avg));
	EXPECT_EQ(1, l_Avg.NoPoints);
	
	ASSERT_EQ(true, pTHM1176->ParmTriggerInputGet(l_Trig));
	EXPECT_EQ(kInputTrigSrcImmediate, l_Trig.Source);
	EXPECT_EQ(1, l_Trig.Count);

	ASSERT_EQ(true, pTHM1176->ParmSleepGet(l_Sleep));
	EXPECT_EQ(false, l_Sleep);

	ASSERT_EQ(true, pTHM1176->ParmUseCalibrationGet(l_UseCal));
	EXPECT_EQ(true, l_UseCal);
}

/// \test Test SwitchToDFUMode method.
TEST_F(CTHM1176MiscUtilitiesTest, DISABLED_SwitchToDFUMode)
{
	// Switch to DFU mode.
	ASSERT_EQ(true, pTHM1176->SwitchToDFUMode());
}

