/*
Copyright (c) 2018, MIPI Alliance, Inc. 
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in
  the documentation and/or other materials provided with the
  distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
 * Contributors:
 * Norbert Schulz (Intel Corporation) - Initial API and implementation
 */

#include <string>
#include <stdint.h>
#include "mipi_syst_gtest.h"

#if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_STATE_DATA) &&\
	defined(MIPI_SYST_PCFG_ENABLE_DEFAULT_SCATTER_WRITE) &&\
	defined(MIPI_SYST_PCFG_ENABLE_PRINTF_API)

#define mipi_syst_write_printf_string(a,b,c, ...) \
	(sstr.str(""),\
	::mipi_syst_write_printf_string(a,b,c, __VA_ARGS__ ),\
	result = sstr.str(),\
	result.c_str())

#define mipi_syst_write_printf_catalog64(a,b,c, ...) \
	(sstr.str(""),\
	::mipi_syst_write_printf_catalog64(a,b,c, __VA_ARGS__ ),\
	result = sstr.str(),\
	result.c_str())

#define mipi_syst_write_printf_catalog32(a,b,c, ...) \
	(sstr.str(""),\
	::mipi_syst_write_printf_catalog32(a,b,c, __VA_ARGS__ ),\
	result = sstr.str(),\
	result.c_str())

class MipiSysTFixturePrintf : public MipiSysTFixtureOutput
{
public:
	void SetUp() {
		MipiSysTFixtureOutput::SetUp();
	}

	void TearDown() {
		MipiSysTFixtureOutput::TearDown();
	}

	static std::string result;
};

std::string MipiSysTFixturePrintf::result;

TEST_F(MipiSysTFixturePrintf, syst_printf_null)
{
	EXPECT_STREQ(
		xform(""),
		MIPI_SYST_PRINTF(0, MIPI_SYST_SEVERITY_INFO, (char*) 0)
		);
	EXPECT_STREQ(
		xform("<D32TS>05012242[typ=2:5 mu=1:2 sev=4 len]<D16>0007<D32>6c756e28<D16>296c<D8>00<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, (char*) 0)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_printf_basic)
{
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0001<D8>00<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "")
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0003<D16>2525<D8>00<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%%")
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000e<D64>6f77206f6c6c6568<D32>20646c72<D16>0021<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "hello world !")
		);
}

TEST_F(MipiSysTFixturePrintf, syst_printf_invalid)
{
	EXPECT_STREQ(
		xform("<D32TS>05012242[typ=2:5 mu=1:2 sev=4 len]<D16>0007<D32>6c756e28<D16>296c<D8>00<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, 0)
		);
	EXPECT_STREQ(
		xform("<D32TS>05012242[typ=2:5 mu=1:2 sev=4 len]<D16>0003<D16>6225<D8>00<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%b", 1)
		);
	std::string tooLong(MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE, 'X');

	EXPECT_STREQ(
		xform("<D32TS>05012242[typ=2:5 mu=1:2 sev=4 len]<D16>0020<D64>5858585858585858<D64>5858585858585858<D64>5858585858585858<D64>5858585858585858<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, tooLong.c_str(), 1)
		);

	tooLong.resize(MIPI_SYST_PCFG_PRINTF_ARGBUF_SIZE /2);
	EXPECT_STREQ(
		xform("<D32TS>05012242[typ=2:5 mu=1:2 sev=4 len]<D16>0006<D32>25207325<D16>0073<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%s %s", tooLong.c_str(), tooLong.c_str())
		);
}
TEST_F(MipiSysTFixturePrintf, syst_printf_flags)
{
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>1122334400642b25<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%+d", 0x11223344)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>1122334400642d25<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%-d", 0x11223344)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>1122334400642025<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "% d", 0x11223344)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>1122334400642325<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%#d", 0x11223344)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>1122334400643025<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%0d", 0x11223344)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_printf_width)
{
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>1122334400643325<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%3d", 0x11223344)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000c<D64>000000ab00642a25<D32>11223344<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%*d", 0xab, 0x11223344)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0012<D64>ccdd00642a2e2a25<D64>334412345678aabb<D16>1122<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%*.*d", 0xaabbccdd, 0x12345678, 0x11223344)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_printf_floatingpoint)
{
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea006625<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%f", 3.14159265359)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea004625<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%F", 3.14159265359)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea006525<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%e", 3.14159265359)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea004525<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%E", 3.14159265359)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea006725<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%g", 3.14159265359)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea006125<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%a", 3.14159265359)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea004125<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%A", 3.14159265359)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea004725<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%G", 3.14159265359)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000c<D64>54442eea00664c25<D32>400921fb<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%Lf", (long double)3.14159265359)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_printf_floatingpoint_precison)
{
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>fb54442eea006625<D16>0921<D8>40<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%f", 3.14159265359)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000c<D64>54442eea00663325<D32>400921fb<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%3f", 3.14159265359)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0010<D64>006630312e313125<D64>400921fb54442eea<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%11.10f", 3.14159265359)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0016<D64>000a00662a2e2a25<D64>2eea0000000b0000<D32>21fb5444<D16>4009<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%*.*f", 10, 11, 3.14159265359)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_printf_modifier)
{
	unsigned int hh = 0x12;
	unsigned short int h = 0x1234;
	long int l = (long int)-1;
	unsigned long long int ll = 0x1122334455667788ull;
	uintmax_t j = 0x1122334455667788ull;
	size_t z = (size_t)-1;
	ptrdiff_t t = (ptrdiff_t)-1;

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0009<D64>0000120064686825<D8>00<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%hhd", hh)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>0000123400646825<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%hd", h)
		);
#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000c<D64>ffffffff00646c25<D32>ffffffff<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%ld", l)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000c<D64>ffffffff00647a25<D32>ffffffff<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%zd", z)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000c<D64>ffffffff00647425<D32>ffffffff<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%td", t)
		);
#else
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>ffffffff00646c25<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%ld", l)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>ffffffff00647a25<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%zd", z)
		);
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>ffffffff00647425<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%td", t)
		);
#endif

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000d<D64>66778800646c6c25<D32>22334455<D8>11<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%lld", ll)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000c<D64>5566778800646a25<D32>11223344<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%jd", j)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_printf_pointer)
{
	void * p = (void*)-1;

	if (sizeof(p) == 8) {
		EXPECT_STREQ(
			xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>000b<D64>ffffffffff007025<D16>ffff<D8>ff<FLAG>"),
			MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%p", p)
			);
	} else {
		EXPECT_STREQ(
			xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0007<D32>ff007025<D16>ffff<D8>ff<FLAG>"),
			MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%p", p)
			);
	}
}

TEST_F(MipiSysTFixturePrintf, syst_printf_char)
{
	char c = 'C';
	wint_t w = 'W';

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0007<D32>43006325<D16>0000<D8>00<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%c", c)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0008<D64>0000005700636c25<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "%lc", w)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_printf_combinations)
{
	EXPECT_STREQ(
		xform("<D32TS>0b012242[typ=2:b mu=1:2 sev=4 len]<D16>0031<D64>6a20732520656854<D64>766f206465706d75<D64>2520656874207265<D64>6d69742064252073<D64>00776f63002e7365<D64>000005006e6f6f6d<D8>00<FLAG>"),
		MIPI_SYST_PRINTF(ph, MIPI_SYST_SEVERITY_INFO, "The %s jumped over the %s %d times.", "cow", "moon", 5)
		);
}
#if defined(MIPI_SYST_PCFG_ENABLE_LOCATION_RECORD)
TEST_F(MipiSysTFixturePrintf, syst_printf_loc)
{
	EXPECT_STREQ(
		xform("<D32TS>0b012342[typ=2:b mu=1:2 sev=4 loc len]<D8>00<D32>5678abcd<D16>0031<D64>6a20732520656854<D64>766f206465706d75<D64>2520656874207265<D64>6d69742064252073<D64>00776f63002e7365<D64>000005006e6f6f6d<D8>00<FLAG>"),
		MIPI_SYST_PRINTF_LOC16(ph, MIPI_SYST_SEVERITY_INFO, 0xabcd, "The %s jumped over the %s %d times.", "cow", "moon", 5)
		);

	EXPECT_STREQ(
		xform("<D32TS>0b012342[typ=2:b mu=1:2 sev=4 loc len]<D8>01<D64>12345678aabbccdd<D16>0031<D64>6a20732520656854<D64>766f206465706d75<D64>2520656874207265<D64>6d69742064252073<D64>00776f63002e7365<D64>000005006e6f6f6d<D8>00<FLAG>"),
		MIPI_SYST_PRINTF_LOC32(ph, MIPI_SYST_SEVERITY_INFO, 0xaabbccdd, "The %s jumped over the %s %d times.", "cow", "moon", 5)
		);

#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
	EXPECT_STREQ(
		xform("<D32TS>0b012342[typ=2:b mu=1:2 sev=4 loc len]<D8>03<D64>12345678aabbccdd<D16>0031<D64>6a20732520656854<D64>766f206465706d75<D64>2520656874207265<D64>6d69742064252073<D64>00776f63002e7365<D64>000005006e6f6f6d<D8>00<FLAG>"),
		MIPI_SYST_PRINTF_LOCADDR(ph, MIPI_SYST_SEVERITY_INFO, "The %s jumped over the %s %d times.", "cow", "moon", 5)
		);
#else
	EXPECT_STREQ(
		xform("<D32TS>0b012342[typ=2:b mu=1:2 sev=4 loc len]<D8>02<D32>12345678<D16>0031<D64>6a20732520656854<D64>766f206465706d75<D64>2520656874207265<D64>6d69742064252073<D64>00776f63002e7365<D64>000005006e6f6f6d<D8>00<FLAG>"),
		MIPI_SYST_PRINTF_LOCADDR(ph, MIPI_SYST_SEVERITY_INFO, "The %s jumped over the %s %d times.", "cow", "moon", 5)
		);
#endif
}
#endif // MIPI_SYST_PCFG_ENABLE_LOCATION_RECORD

#if defined(MIPI_SYST_PCFG_ENABLE_CATID64_API)

TEST_F(MipiSysTFixturePrintf, syst_catalog64_printf_null)
{
	EXPECT_STREQ(
		xform(""),
		MIPI_SYST_CATPRINTF64(NULL, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788, "")
		);
}

TEST_F(MipiSysTFixturePrintf, syst_catalog64_printf_invalid)
{
	EXPECT_STREQ(
		xform("<D32TS>05012242[typ=2:5 mu=1:2 sev=4 len]<D16>0007<D32>61746163<D16>6772<D8>00<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344, -1, -1)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_catalog64_printf_basic)
{
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0008<D64>1122334455667788<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788, "")
		);

	// check that formt string is not added into payload
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0008<D64>1122334455667788<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull, "Hello world")
		);

	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>000c<D64>1122334455667788<D32>00000058<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%c", MIPI_SYST_PARAM_CHAR('X'))
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>000c<D64>1122334455667788<D32>00000058<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%c", MIPI_SYST_PARAM_WCHAR(L'X'))
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>000c<D64>1122334455667788<D32>abcd1234<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%c", MIPI_SYST_PARAM_INT(0xabcd1234))
		);

	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0010<D64>1122334455667788<D64>1234567887654321<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%lld", MIPI_SYST_PARAM_LONGLONG(0x1234567887654321ull))
		);

#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0010<D64>1122334455667788<D64>0000000012345678<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%ld", MIPI_SYST_PARAM_LONG(0x12345678))
		);

	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0010<D64>1122334455667788<D64>1234567887654321<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%z", MIPI_SYST_PARAM_SIZE_T(0x1234567887654321ull))
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0010<D64>1122334455667788<D64>1234567887654321<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%t", MIPI_SYST_PARAM_PTRDIFF_T(0x1234567887654321ull))
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0010<D64>1122334455667788<D64>1234567887654321<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%p", MIPI_SYST_PARAM_PTR(0x1234567887654321ull))
		);
#else
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>000c<D64>1122334455667788<D32>12345678<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%ld", MIPI_SYST_PARAM_LONG(0x12345678))
		);

	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>000c<D64>1122334455667788<D32>12345678<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%z", MIPI_SYST_PARAM_SIZE_T(0x12345678))
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>000c<D64>1122334455667788<D32>12345678<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%t", MIPI_SYST_PARAM_PTRDIFF_T(0x12345678))
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>000c<D64>1122334455667788<D32>12345678<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%p", MIPI_SYST_PARAM_PTR(0x12345678))
		);
#endif //defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)

	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0010<D64>1122334455667788<D64>4000000000000000<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%f", MIPI_SYST_PARAM_FLOAT((float)2.0))
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0010<D64>1122334455667788<D64>4000000000000000<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%f", MIPI_SYST_PARAM_DOUBLE((double)2.0))
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0010<D64>1122334455667788<D64>4000000000000000<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788ull,
		"%lf", MIPI_SYST_PARAM_LONGDOUBLE((long double)2.0))
		);
}

TEST_F(MipiSysTFixturePrintf, syst_catalog64_printf_string)
{
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0009<D64>1122334455667788<D8>00<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788,
		"%s", MIPI_SYST_PARAM_CSTR(""))
		);

	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0016<D64>1122334455667788<D64>6f77206f6c6c6568<D32>20646c72<D16>0021<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788,
		"%s", MIPI_SYST_PARAM_CSTR("hello world !"))
		);

	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>0035<D64>1122334455667788<D64>3333003232003100<D64>3500343434340033<D64>3636360035353535<D64>3737373700363636<D64>3838383800373737<D32>38383838<D8>00<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788,
		"%s",
		MIPI_SYST_PARAM_CSTR(""),
		MIPI_SYST_PARAM_CSTR("1"),
		MIPI_SYST_PARAM_CSTR("22"),
		MIPI_SYST_PARAM_CSTR("333"),
		MIPI_SYST_PARAM_CSTR("4444"),
		MIPI_SYST_PARAM_CSTR("55555"),
		MIPI_SYST_PARAM_CSTR("666666"),
		MIPI_SYST_PARAM_CSTR("7777777"),
		MIPI_SYST_PARAM_CSTR("88888888")
		)
		);
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>001e<D64>1122334455667788<D64>6f77206f6c6c6568<D64>3231002120646c72<D32>12340033<D16>abcd<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788,
		"%s %s %d",
		MIPI_SYST_PARAM_CSTR("hello world !"),
		MIPI_SYST_PARAM_CSTR("123"),
		MIPI_SYST_PARAM_INT(0xabcd1234)
		)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_catalog64_printf_mixed)
{
	EXPECT_STREQ(
		xform("<D32TS>02012243[typ=3:2 mu=1:2 sev=4 len]<D16>001e<D64>1122334455667788<D64>6f77206f6c6c6568<D64>3231002120646c72<D32>12340033<D16>abcd<FLAG>"),
		MIPI_SYST_CATPRINTF64(ph, MIPI_SYST_SEVERITY_INFO, 0x1122334455667788,
		"%s %s %d",
		MIPI_SYST_PARAM_CSTR("hello world !"),
		MIPI_SYST_PARAM_CSTR("123"),
		MIPI_SYST_PARAM_INT(0xabcd1234)
		)
		);
}
#endif // #if defined(MIPI_SYST_PCFG_ENABLE_CATID64_API)

#if defined(MIPI_SYST_PCFG_ENABLE_CATID32_API)

TEST_F(MipiSysTFixturePrintf, syst_catalog32_printf_null)
{
	EXPECT_STREQ(
		xform(""),
		MIPI_SYST_CATPRINTF32(NULL, MIPI_SYST_SEVERITY_INFO, 0x11223344, "")
		);
}

TEST_F(MipiSysTFixturePrintf, syst_catalog32_printf_invalid)
{
	EXPECT_STREQ(
		xform("<D32TS>05012242[typ=2:5 mu=1:2 sev=4 len]<D16>0007<D32>61746163<D16>6772<D8>00<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344, -1, -1)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_catalog32_printf_basic)
{
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0004<D32>11223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344, "")
		);

	// check that format string is not added into payload
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0004<D32>11223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull, "Hello world")
		);

	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0008<D64>0000005811223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%c", MIPI_SYST_PARAM_CHAR('X'))
		);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0008<D64>0000123411223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
			"%hhd", MIPI_SYST_PARAM_SHORT(0x1234))
	);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0008<D64>0000005811223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%lc", MIPI_SYST_PARAM_WCHAR(L'X'))
		);

	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0008<D64>abcd123411223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%d", MIPI_SYST_PARAM_INT(0xabcd1234))
		);

	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>000c<D64>8765432111223344<D32>12345678<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%lld", MIPI_SYST_PARAM_LONGLONG(0x1234567887654321ull))
		);

#if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>000c<D64>1234567811223344<D32>00000000<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%ld", MIPI_SYST_PARAM_LONG(0x12345678))
		);

	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>000c<D64>8765432111223344<D32>12345678<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%z", MIPI_SYST_PARAM_SIZE_T(0x1234567887654321ull))
		);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>000c<D64>8765432111223344<D32>12345678<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%t", MIPI_SYST_PARAM_PTRDIFF_T(0x1234567887654321ull))
		);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>000c<D64>8765432111223344<D32>12345678<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%p", MIPI_SYST_PARAM_PTR(0x1234567887654321ull))
		);
#else
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0008<D64>1234567811223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%ld", MIPI_SYST_PARAM_LONG(0x12345678))
		);

	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0008<D64>1234567811223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%z", MIPI_SYST_PARAM_SIZE_T(0x12345678))
		);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0008<D64>1234567811223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%t", MIPI_SYST_PARAM_PTRDIFF_T(0x12345678))
		);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0008<D64>1234567811223344<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%p", MIPI_SYST_PARAM_PTR(0x12345678))
		);
#endif //defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)

	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>000c<D64>0000000011223344<D32>40000000<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%f", MIPI_SYST_PARAM_FLOAT((float)2.0))
		);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>000c<D64>0000000011223344<D32>40000000<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%f", MIPI_SYST_PARAM_DOUBLE((double)2.0))
		);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>000c<D64>0000000011223344<D32>40000000<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344ull,
		"%lf", MIPI_SYST_PARAM_LONGDOUBLE((long double)2.0))
		);
}

TEST_F(MipiSysTFixturePrintf, syst_catalog32_printf_string)
{
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0005<D32>11223344<D8>00<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344,
		"%s", MIPI_SYST_PARAM_CSTR(""))
		);

	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0012<D64>6c6c656811223344<D64>20646c726f77206f<D16>0021<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344,
		"%s", MIPI_SYST_PARAM_CSTR("hello world !"))
		);

	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>0031<D64>3200310011223344<D64>3434003333330032<D64>3535353535003434<D64>0036363636363600<D64>0037373737373737<D64>3838383838383838<D8>00<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344,
		"%s",
		MIPI_SYST_PARAM_CSTR(""),
		MIPI_SYST_PARAM_CSTR("1"),
		MIPI_SYST_PARAM_CSTR("22"),
		MIPI_SYST_PARAM_CSTR("333"),
		MIPI_SYST_PARAM_CSTR("4444"),
		MIPI_SYST_PARAM_CSTR("55555"),
		MIPI_SYST_PARAM_CSTR("666666"),
		MIPI_SYST_PARAM_CSTR("7777777"),
		MIPI_SYST_PARAM_CSTR("88888888")
		)
		);
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>001a<D64>6c6c656811223344<D64>20646c726f77206f<D64>1234003332310021<D16>abcd<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344,
		"%s %s %d",
		MIPI_SYST_PARAM_CSTR("hello world !"),
		MIPI_SYST_PARAM_CSTR("123"),
		MIPI_SYST_PARAM_INT(0xabcd1234)
		)
		);
}

TEST_F(MipiSysTFixturePrintf, syst_catalog32_printf_mixed)
{
	EXPECT_STREQ(
		xform("<D32TS>01012243[typ=3:1 mu=1:2 sev=4 len]<D16>001a<D64>6c6c656811223344<D64>20646c726f77206f<D64>1234003332310021<D16>abcd<FLAG>"),
		MIPI_SYST_CATPRINTF32(ph, MIPI_SYST_SEVERITY_INFO, 0x11223344,
		"%s %s %d",
		MIPI_SYST_PARAM_CSTR("hello world !"),
		MIPI_SYST_PARAM_CSTR("123"),
		MIPI_SYST_PARAM_INT(0xabcd1234)
		)
		);
}
#endif // #if defined(MIPI_SYST_PCFG_ENABLE_CATID32_API)
#endif //MIPI_SYST_PCFG_ENABLE_PLATFORM_STATE_DATA && MIPI_SYST_PCFG_ENABLE_DEFAULT_SCATTER_WRITE && MIPI_SYST_PCFG_ENABLE_PRINTF_API