/*
 * 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 "util/compare.h"
#include "xml/xlevel.h"
#include "logunit.h"
#include "testchar.h"
#include <log4cxx/spi/loggerrepository.h>

using namespace log4cxx;

/**
Test the configuration of the hierarchy-wide threshold.
*/
LOGUNIT_CLASS(HierarchyThresholdTestCase)
{
	LOGUNIT_TEST_SUITE(HierarchyThresholdTestCase);
	LOGUNIT_TEST(test1);
	LOGUNIT_TEST(test2);
	LOGUNIT_TEST(test3);
	LOGUNIT_TEST(test4);
	LOGUNIT_TEST(test5);
	LOGUNIT_TEST(test6);
	LOGUNIT_TEST(test7);
	LOGUNIT_TEST(test8);
	LOGUNIT_TEST_SUITE_END();


public:
	void setUp()
	{
	}

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

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

	void test1()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold1.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/hierarchyThreshold.1")));
	}

	void test2()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold2.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/hierarchyThreshold.2")));
	}

	void test3()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold3.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/hierarchyThreshold.3")));
	}

	void test4()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold4.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/hierarchyThreshold.4")));
	}

	void test5()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold5.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/hierarchyThreshold.5")));
	}

	void test6()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold6.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/hierarchyThreshold.6")));
	}

	void test7()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold7.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/hierarchyThreshold.7")));
	}

	void test8()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold8.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/hierarchyThreshold.8")));
	}

	static void common()
	{
		logger->log(XLevel::getTrace(), LOG4CXX_TEST_STR("m0"));
		logger->debug(LOG4CXX_TEST_STR("m1"));
		logger->info(LOG4CXX_TEST_STR("m2"));
		logger->warn(LOG4CXX_TEST_STR("m3"));
		logger->error(LOG4CXX_TEST_STR("m4"));
		logger->fatal(LOG4CXX_TEST_STR("m5"));
	}

private:
	static File TEMP;
	static LoggerPtr logger;
};

File HierarchyThresholdTestCase::TEMP(LOG4CXX_FILE("output/hierarchythreshold"));

LoggerPtr HierarchyThresholdTestCase::logger =
	Logger::getLogger(LOG4CXX_TEST_STR("HierarchyThresholdTestCase"));

LOGUNIT_TEST_SUITE_REGISTRATION(HierarchyThresholdTestCase);
