
/*
 * 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/ndc.h>
#include <log4cxx/file.h>
#include <log4cxx/logger.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/patternlayout.h>
#include "insertwide.h"
#include "logunit.h"
#include "util/compare.h"

static log4cxx::NDC ndc("ndctest");

using namespace log4cxx;

LOGUNIT_CLASS(NDCTestCase)
{
	static File TEMP;
	static LoggerPtr logger;

	LOGUNIT_TEST_SUITE(NDCTestCase);
	LOGUNIT_TEST(testPushPop);
	LOGUNIT_TEST(test1);
	LOGUNIT_TEST(testInherit);
	LOGUNIT_TEST(testFieldPrecision);
	LOGUNIT_TEST_SUITE_END();

public:

	void setUp()
	{
	}

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

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

	/**
	 *   Push and pop a value from the NDC
	 */
	void testPushPop()
	{
		NDC::push("trivial context");
		LogString actual(NDC::pop());
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("trivial context"), actual);
	}


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

	static void common()
	{
		commonLog();
		NDC::push("n1");
		commonLog();
		NDC::push("n2");
		NDC::push("n3");
		commonLog();
		NDC::pop();
		commonLog();
		NDC::clear();
		commonLog();
	}

	static void commonLog()
	{
		LOG4CXX_DEBUG(logger, "m1");
		LOG4CXX_INFO(logger, "m2");
		LOG4CXX_WARN(logger, "m3");
		LOG4CXX_ERROR(logger, "m4");
		LOG4CXX_FATAL(logger, "m5");
	}

	void testInherit()
	{
		NDC::push("hello");
		NDC::push("world");
		NDC::Stack* clone = NDC::cloneStack();
		NDC::clear();
		NDC::push("discard");
		NDC::inherit(clone);
		LogString expected1(LOG4CXX_STR("world"));
		LOGUNIT_ASSERT_EQUAL(expected1, NDC::pop());
		LogString expected2(LOG4CXX_STR("hello"));
		LOGUNIT_ASSERT_EQUAL(expected2, NDC::pop());
		LogString expected3;
		LOGUNIT_ASSERT_EQUAL(expected3, NDC::pop());
	}

	/// Check NDC formatting uses to suffix when the maximum field length is exceeded.
	void testFieldPrecision()
	{
		NDC item1("context1");
		NDC item2("context2");
		NDC item3("context3");
		helpers::Pool p;
		LogString output;
		PatternLayout l{ LOG4CXX_STR("%-5p %c - %.20x %m") };
		l.format(output, std::make_shared<spi::LoggingEvent>(LOG4CXX_STR("NDC.LayoutTest"), Level::getInfo(), LOG4CXX_STR("Message"), spi::LocationInfo::getLocationUnavailable()), p);
		LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("INFO  NDC.LayoutTest - t1 context2 context3 Message"), output);
	}

};


File NDCTestCase::TEMP("output/ndc");
LoggerPtr NDCTestCase::logger(Logger::getLogger("org.apache.log4j.NDCTestCase"));

LOGUNIT_TEST_SUITE_REGISTRATION(NDCTestCase);
