/*
 * 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);
#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));
	}
#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);
