/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

#include <log4cxx/helpers/transcoder.h>
#include "../insertwide.h"
#include "../logunit.h"


using namespace log4cxx;
using namespace log4cxx::helpers;


LOGUNIT_CLASS(TranscoderTestCase)
{
	LOGUNIT_TEST_SUITE(TranscoderTestCase);
	LOGUNIT_TEST(decode1);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(decode2);
#endif
	LOGUNIT_TEST(decode3);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(decode4);
#endif
	LOGUNIT_TEST(decode7);
	LOGUNIT_TEST(decode8);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(encode1);
#endif
	LOGUNIT_TEST(encode2);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(encode3);
	LOGUNIT_TEST(encode3_1);
#endif
	LOGUNIT_TEST(encode4);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(encode5);
#endif
	LOGUNIT_TEST(encode6);
	LOGUNIT_TEST(testDecodeUTF8_1);
	LOGUNIT_TEST(testDecodeUTF8_2);
	LOGUNIT_TEST(testDecodeUTF8_3);
	LOGUNIT_TEST(testDecodeUTF8_4);
#if LOG4CXX_UNICHAR_API
	LOGUNIT_TEST(udecode2);
	LOGUNIT_TEST(udecode4);
	LOGUNIT_TEST(uencode1);
	LOGUNIT_TEST(uencode3);
	LOGUNIT_TEST(uencode5);
#endif
#if LOG4CXX_LOGCHAR_IS_UTF8
	LOGUNIT_TEST(encodeCharsetName1);
	LOGUNIT_TEST(encodeCharsetName2);
	LOGUNIT_TEST(encodeCharsetName3);
#endif
	LOGUNIT_TEST_SUITE_END();


public:
	void decode1()
	{
		const char* greeting = "Hello, World";
		LogString decoded(LOG4CXX_STR("foo\n"));
		Transcoder::decode(greeting, decoded);
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\nHello, World"), decoded);
	}

#if LOG4CXX_WCHAR_T_API
	void decode2()
	{
		const wchar_t* greeting = L"Hello, World";
		LogString decoded(LOG4CXX_STR("foo\n"));
		Transcoder::decode(greeting, decoded);
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\nHello, World"), decoded);
	}
#endif

	void decode3()
	{
		const char* nothing = "";
		LogString decoded(LOG4CXX_STR("foo\n"));
		Transcoder::decode(nothing, decoded);
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\n"), decoded);
	}

#if LOG4CXX_WCHAR_T_API
	void decode4()
	{
		const wchar_t* nothing = L"";
		LogString decoded(LOG4CXX_STR("foo\n"));
		Transcoder::decode(nothing, decoded);
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\n"), decoded);
	}
#endif


	enum { BUFSIZE = 255 };

	void decode7()
	{
		//
		//   normal characters striding over a buffer boundary
		//
		std::string longMsg(BUFSIZE - 2, 'A');
		longMsg.append("Hello");
		LogString decoded;
		Transcoder::decode(longMsg, decoded);
		LOGUNIT_ASSERT_EQUAL((size_t) BUFSIZE + 3, decoded.length());
		LOGUNIT_ASSERT_EQUAL(LogString(BUFSIZE - 2, LOG4CXX_STR('A')),
			decoded.substr(0, BUFSIZE - 2));
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("Hello"),
			decoded.substr(BUFSIZE - 2 ));
	}

	void decode8()
	{
		std::string msg("Hello, World.");
		LogString actual;
		Transcoder::decode(msg, actual);
		LogString expected(LOG4CXX_STR("Hello, World."));
		LOGUNIT_ASSERT_EQUAL(expected, actual);
	}


#if LOG4CXX_WCHAR_T_API
	void encode1()
	{
		const LogString greeting(LOG4CXX_STR("Hello, World"));
		std::wstring encoded;
		Transcoder::encode(greeting, encoded);
		LOGUNIT_ASSERT_EQUAL((std::wstring) L"Hello, World", encoded);
	}
#endif

	void encode2()
	{
		const LogString greeting(LOG4CXX_STR("Hello, World"));
		std::string encoded;
		Transcoder::encode(greeting, encoded);
		LOGUNIT_ASSERT_EQUAL((std::string) "Hello, World", encoded);
	}

#if LOG4CXX_WCHAR_T_API
	void encode3()
	{
		LogString greeting(BUFSIZE - 3, LOG4CXX_STR('A'));
		greeting.append(LOG4CXX_STR("Hello"));
		std::wstring encoded;
		Transcoder::encode(greeting, encoded);
		std::wstring manyAs(BUFSIZE - 3, L'A');
		LOGUNIT_ASSERT_EQUAL(manyAs, encoded.substr(0, BUFSIZE - 3));
		LOGUNIT_ASSERT_EQUAL(std::wstring(L"Hello"), encoded.substr(BUFSIZE - 3));
	}

	void encode3_1()
	{
		// Test invalid multibyte string
		LogString greeting;
		greeting.push_back( 0xff );
		std::wstring encoded;
		Transcoder::encode(greeting, encoded);

		std::wstring expected;
		expected.push_back( log4cxx::helpers::Transcoder::LOSSCHAR );
		LOGUNIT_ASSERT_EQUAL(encoded, expected );
	}
#endif

	void encode4()
	{
		LogString greeting(BUFSIZE - 3, LOG4CXX_STR('A'));
		greeting.append(LOG4CXX_STR("Hello"));
		std::string encoded;
		Transcoder::encode(greeting, encoded);
		std::string manyAs(BUFSIZE - 3, 'A');
		LOGUNIT_ASSERT_EQUAL(manyAs, encoded.substr(0, BUFSIZE - 3));
		LOGUNIT_ASSERT_EQUAL(std::string("Hello"), encoded.substr(BUFSIZE - 3));
	}

#if LOG4CXX_WCHAR_T_API
	void encode5()
	{
		//   arbitrary, hopefully meaningless, characters from
		//     Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
		const wchar_t greeting[] = { L'A', 0x0605, 0x0530, 0x984, 0x40E3, 0x400, 0 };
		//
		//  decode to LogString (UTF-16 or UTF-8)
		//
		LogString decoded;
		Transcoder::decode(greeting, decoded);
		//
		//  decode to wstring
		//
		std::wstring encoded;
		Transcoder::encode(decoded, encoded);
		//
		//   should be lossless
		//
		LOGUNIT_ASSERT_EQUAL((std::wstring) greeting, encoded);
	}
#endif

	void encode6()
	{
#if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_LOGCHAR_IS_UNICHAR
		//   arbitrary, hopefully meaningless, characters from
		//     Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
		const logchar greeting[] = { L'A', 0x0605, 0x0530, 0x984, 0x40E3, 0x400, 0 };
#endif

#if LOG4CXX_LOGCHAR_IS_UTF8
		const char greeting[] = { 'A',
				(char) 0xD8, (char) 0x85,
				(char) 0xD4, (char) 0xB0,
				(char) 0xE0, (char) 0xCC, (char) 0x84,
				(char) 0xE8, (char) 0x87, (char) 0x83,
				(char) 0xD0, (char) 0x80,
				0
			};
#endif

		//
		//  decode to LogString (UTF-16 or UTF-8)
		//
		LogString decoded;
		Transcoder::decode(greeting, decoded);
		//
		//  decode to wstring
		//
		std::string encoded;
		//
		//   likely 'A\u0605\u0530\u0984\u40E3\u0400'
		//
		Transcoder::encode(decoded, encoded);
	}

	void testDecodeUTF8_1()
	{
		std::string src("a");
		LogString out;
		Transcoder::decodeUTF8(src, out);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("a")), out);
	}

	void testDecodeUTF8_2()
	{
		std::string src(1, 0x80);
		LogString out;
		Transcoder::decodeUTF8(src, out);
		LOGUNIT_ASSERT_EQUAL(LogString(1, Transcoder::LOSSCHAR), out);
	}

	void testDecodeUTF8_3()
	{
		std::string src("\xC2");
		LogString out;
		Transcoder::decodeUTF8(src, out);
		LOGUNIT_ASSERT_EQUAL(LogString(1, Transcoder::LOSSCHAR), out);
	}

	void testDecodeUTF8_4()
	{
		std::string src("\xC2\xA9");
		LogString out;
		Transcoder::decodeUTF8(src, out);
		LogString::const_iterator iter = out.begin();
		unsigned int sv = Transcoder::decode(out, iter);
		LOGUNIT_ASSERT_EQUAL((unsigned int) 0xA9, sv);
		LOGUNIT_ASSERT_EQUAL(true, iter == out.end());
	}


#if LOG4CXX_UNICHAR_API
	void udecode2()
	{
		const UniChar greeting[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', 0 };
		LogString decoded(LOG4CXX_STR("foo\n"));
		Transcoder::decode(greeting, decoded);
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\nHello, World"), decoded);
	}

	void udecode4()
	{
		const UniChar nothing[] = { 0 };
		LogString decoded(LOG4CXX_STR("foo\n"));
		Transcoder::decode(nothing, decoded);
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\n"), decoded);
	}

	void uencode1()
	{
		const LogString greeting(LOG4CXX_STR("Hello, World"));
		std::basic_string<UniChar> encoded;
		Transcoder::encode(greeting, encoded);
		const UniChar expected[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', 0 };
		LOGUNIT_ASSERT_EQUAL(std::basic_string<UniChar>(expected), encoded);
	}

	void uencode3()
	{
		LogString greeting(BUFSIZE - 3, LOG4CXX_STR('A'));
		greeting.append(LOG4CXX_STR("Hello"));
		std::basic_string<UniChar> encoded;
		Transcoder::encode(greeting, encoded);
		std::basic_string<UniChar> manyAs(BUFSIZE - 3, 'A');
		LOGUNIT_ASSERT_EQUAL(manyAs, encoded.substr(0, BUFSIZE - 3));
		const UniChar hello[] = { 'H', 'e', 'l', 'l', 'o', 0 };
		LOGUNIT_ASSERT_EQUAL(std::basic_string<UniChar>(hello), encoded.substr(BUFSIZE - 3));
	}

	void uencode5()
	{
		//   arbitrary, hopefully meaningless, characters from
		//     Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
		const UniChar greeting[] = { L'A', 0x0605, 0x0530, 0x984, 0x40E3, 0x400, 0 };
		//
		//  decode to LogString (UTF-16 or UTF-8)
		//
		LogString decoded;
		Transcoder::decode(greeting, decoded);
		//
		//  decode to basic_string<UniChar>
		//
		std::basic_string<UniChar> encoded;
		Transcoder::encode(decoded, encoded);
		//
		//   should be lossless
		//
		LOGUNIT_ASSERT_EQUAL(std::basic_string<UniChar>(greeting), encoded);
	}
#endif

#if LOG4CXX_LOGCHAR_IS_UTF8
	void encodeCharsetName1()
	{
		const logchar utf8[] = { 0x75, 0x74, 0x66, 0x2D, 0x38, 0x00 };
		std::string encoded(Transcoder::encodeCharsetName(LogString(utf8)));
		LOGUNIT_ASSERT_EQUAL(std::string("utf-8"), encoded);
	}

	void encodeCharsetName2()
	{
		logchar lascii[0x60];
		char ascii[0x60];

		for (int i = 0; i < 0x5F; i++)
		{
			lascii[i] = i + 0x20;
			ascii[i] = i + 0x20;
		}

		lascii[0x5F] = 0;
		ascii[0x5F] = 0;
		std::string encoded(Transcoder::encodeCharsetName(LogString(ascii)));
		LOGUNIT_ASSERT_EQUAL(std::string(" !\"#$%&'()*+,-./"), encoded.substr(0, 0x10));

		if (0x40 == 'A')
		{
			LOGUNIT_ASSERT_EQUAL(std::string(ascii), encoded);
		}
	}

	void encodeCharsetName3()
	{
		logchar unsupported[] = { 0x1F, 0x7F, static_cast<logchar>(0x80), static_cast<logchar>(0x81), 0x00 };
		std::string encoded(Transcoder::encodeCharsetName(LogString(unsupported)));
		LOGUNIT_ASSERT_EQUAL(std::string("????"), encoded);
	}
#endif

};

LOGUNIT_TEST_SUITE_REGISTRATION(TranscoderTestCase);
