/*
 * 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/logger.h>
#include "logunit.h"
//
//  If there is no support for wchar_t logging then
//     there is not a consistent way to get the test characters logged
//
#if LOG4CXX_WCHAR_T_API


#include <log4cxx/patternlayout.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/level.h>

#include "util/binarycompare.h"
#include <log4cxx/file.h>
#include <log4cxx/helpers/pool.h>

using namespace log4cxx;
using namespace log4cxx::util;
using namespace log4cxx::helpers;

/**
 * Tests support for encoding specification.
 *
 *
 */
LOGUNIT_CLASS(EncodingTest)
{
	LOGUNIT_TEST_SUITE(EncodingTest);
	LOGUNIT_TEST(testASCII);
	LOGUNIT_TEST(testLatin1);
	LOGUNIT_TEST(testUtf8);
	LOGUNIT_TEST(testUtf16);
	LOGUNIT_TEST(testUtf16LE);
	LOGUNIT_TEST(testUtf16BE);
	LOGUNIT_TEST_SUITE_END();
public:
	/**
	 * Resets configuration after each test.
	 */
	void tearDown()
	{
		auto rep = Logger::getRootLogger()->getLoggerRepository();

		if (rep)
		{
			rep->resetConfiguration();
		}
	}


	/**
	 * Test us-ascii encoding.
	 */
	void testASCII()
	{
		LoggerPtr root(Logger::getRootLogger());

		configure(root, LOG4CXX_STR("output/encoding/ascii.log"),
			LOG4CXX_STR("US-ASCII"));
		common(root);

		BinaryCompare::compare( "output/encoding/ascii.log",
			"witness/encoding/ascii.log");
	}

	/**
	 * Test iso-8859-1 encoding.
	 */
	void testLatin1()
	{
		LoggerPtr root(Logger::getRootLogger());

		configure(root, LOG4CXX_STR("output/encoding/latin1.log"),
			LOG4CXX_STR("iso-8859-1"));
		common(root);

		BinaryCompare::compare( "output/encoding/latin1.log",
			"witness/encoding/latin1.log");
	}

	/**
	 * Test utf-8 encoding.
	 */
	void testUtf8()
	{
		LoggerPtr root(Logger::getRootLogger());

		configure(root, LOG4CXX_STR("output/encoding/UTF-8.log"),
			LOG4CXX_STR("UTF-8"));
		common(root);

		BinaryCompare::compare( "output/encoding/UTF-8.log",
			"witness/encoding/UTF-8.log");
	}

	/**
	 * Test utf-16 encoding.
	 */
	void testUtf16()
	{
		LoggerPtr root(Logger::getRootLogger());

		configure(root, LOG4CXX_STR("output/encoding/UTF-16.log"),
			LOG4CXX_STR("UTF-16"));
		common(root);

		BinaryCompare::compare( "output/encoding/UTF-16.log",
			"witness/encoding/UTF-16.log");
	}

	/**
	 * Test utf-16be encoding.
	 */
	void testUtf16BE()
	{
		LoggerPtr root(Logger::getRootLogger());

		configure(root, LOG4CXX_STR("output/encoding/UTF-16BE.log"),
			LOG4CXX_STR("UTF-16BE"));
		common(root);

		BinaryCompare::compare( "output/encoding/UTF-16BE.log",
			"witness/encoding/UTF-16BE.log");
	}

	/**
	 * Test utf16-le encoding.
	 */
	void testUtf16LE()
	{
		LoggerPtr root(Logger::getRootLogger());

		configure(root, LOG4CXX_STR("output/encoding/UTF-16LE.log"),
			LOG4CXX_STR("UTF-16LE"));
		common(root);

		BinaryCompare::compare( "output/encoding/UTF-16LE.log",
			"witness/encoding/UTF-16LE.log");
	}

	/**
	 * Configure logging.
	 * @param logger logger
	 * @param filename logging file name
	 * @param encoding encoding
	 */
private:
	void configure(      LoggerPtr & logger,
		const LogString & filename,
		const LogString & encoding)
	{
		FileAppenderPtr  appender(new FileAppender());
		PatternLayoutPtr layout(new PatternLayout());
		Pool             p;

		layout->setConversionPattern(LOG4CXX_STR("%p - %m\n"));
		layout->activateOptions(p);

		appender->setAppend(false);
		appender->setEncoding(encoding);
		appender->setFile(filename);
		appender->setLayout(layout);
		appender->activateOptions(p);

		logger->addAppender(appender);
		logger->setLevel(Level::getInfo());
	}

	/**
	 * Common logging requests.
	 * @param logger logger
	 */
	void common(LoggerPtr & logger)
	{
		logger->info("Hello, World");

		// pi can be encoded in iso-8859-1
		const wchar_t pi[] = { 0x00B9, 0 };
		logger->info(pi);

		//   arbitrary, hopefully meaningless, characters from
		//     Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
		const wchar_t greeting[] = { L'A', 0x0605, 0x0530, 0x986, 0x4E03, 0x400, 0 };
		logger->info(greeting);
	}
};

LOGUNIT_TEST_SUITE_REGISTRATION(EncodingTest);

#endif

