/*
 * 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 <log4cxx/propertyconfigurator.h>
#include <log4cxx/helpers/propertyresourcebundle.h>
#include <log4cxx/helpers/locale.h>

#include "util/compare.h"

#include <vector>
#include <sstream>

#include "testchar.h"
#include "logunit.h"
#include <log4cxx/spi/loggerrepository.h>


typedef std::basic_ostringstream<testchar> StringBuffer;

using namespace log4cxx;
using namespace log4cxx::helpers;

LOGUNIT_CLASS(L7dTestCase)
{
	LOGUNIT_TEST_SUITE(L7dTestCase);
	LOGUNIT_TEST(test1);
	LOGUNIT_TEST_SUITE_END();

	LoggerPtr root;
	ResourceBundlePtr bundles[3];

public:
	void setUp()
	{
		Locale localeUS(LOG4CXX_STR("en"), LOG4CXX_STR("US"));
		bundles[0] =
			ResourceBundle::getBundle(LOG4CXX_STR("L7D"), localeUS);
		LOGUNIT_ASSERT(bundles[0] != 0);

		Locale localeFR(LOG4CXX_STR("fr"), LOG4CXX_STR("FR"));
		bundles[1] =
			ResourceBundle::getBundle(LOG4CXX_STR("L7D"), localeFR);
		LOGUNIT_ASSERT(bundles[1] != 0);

		Locale localeCH(LOG4CXX_STR("fr"), LOG4CXX_STR("CH"));
		bundles[2] =
			ResourceBundle::getBundle(LOG4CXX_STR("L7D"), localeCH);
		LOGUNIT_ASSERT(bundles[2] != 0);

		root = Logger::getRootLogger();
	}

	void tearDown()
	{
		auto rep = root->getLoggerRepository();

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

	void test1()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/l7d1.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);

		log4cxx::helpers::Pool pool;

		for (int i = 0; i < 3; i++)
		{
			root->setResourceBundle(bundles[i]);

			LOG4CXX_L7DLOG(root, Level::getDebug(), LOG4CXX_TEST_STR("bogus1"));
			LOG4CXX_L7DLOG(root, Level::getInfo(), LOG4CXX_TEST_STR("test"));
			LOG4CXX_L7DLOG(root, Level::getWarn(), LOG4CXX_TEST_STR("hello_world"));


			StringBuffer os;
			os << (i + 1);
			LOG4CXX_L7DLOG2(root, Level::getDebug(), LOG4CXX_TEST_STR("msg1"), os.str().c_str(),
				LOG4CXX_TEST_STR("log4j"));
			LOG4CXX_L7DLOG2(root, Level::getError(), LOG4CXX_TEST_STR("bogusMsg"), os.str().c_str(),
				LOG4CXX_TEST_STR("log4j"));
			LOG4CXX_L7DLOG2(root, Level::getError(), LOG4CXX_TEST_STR("msg1"), os.str().c_str(),
				LOG4CXX_TEST_STR("log4j"));
			LOG4CXX_L7DLOG(root, Level::getInfo(), LOG4CXX_TEST_STR("bogus2"));

			LOG4CXX_L7DLOG3(root, Level::getError(), LOG4CXX_TEST_STR("msg3"), os.str().c_str(),
				LOG4CXX_TEST_STR("log4j"), LOG4CXX_TEST_STR("log4cxx"));
		}

		LOGUNIT_ASSERT(Compare::compare(LOG4CXX_FILE("output/l7d1"),
				LOG4CXX_FILE("witness/l7d.1")));
	}

};

LOGUNIT_TEST_SUITE_REGISTRATION(L7dTestCase);
