/*
 * 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 "fileappendertestcase.h"
#include <log4cxx/fileappender.h>
#include "insertwide.h"

using namespace log4cxx;
using namespace log4cxx::helpers;

WriterAppender* FileAppenderAbstractTestCase::createWriterAppender() const
{
	return createFileAppender();
}


/**
   Unit tests of log4cxx::FileAppender
 */
class FileAppenderTestCase : public FileAppenderAbstractTestCase
{
		LOGUNIT_TEST_SUITE(FileAppenderTestCase);
		//
		//    tests inherited from AppenderSkeletonTestCase
		//
		LOGUNIT_TEST(testDefaultThreshold);
		LOGUNIT_TEST(testSetOptionThreshold);

		//  tests defined here
		LOGUNIT_TEST(testSetDoubleBackslashes);
		LOGUNIT_TEST(testStripDuplicateBackslashes);
		LOGUNIT_TEST(testNegativeBufferSizeOptionFallsBack);
		LOGUNIT_TEST(testOversizedBufferSizeOptionFallsBack);
		LOGUNIT_TEST(testSetBufferSizeNormalizesNegativeValue);

		LOGUNIT_TEST_SUITE_END();




	public:

		FileAppender* createFileAppender() const
		{
			return new log4cxx::FileAppender();
		}

		void testSetDoubleBackslashes()
		{
			FileAppender appender;
			appender.setOption(LOG4CXX_STR("FILE"), LOG4CXX_STR("output\\\\temp"));
			const File& file = appender.getFile();
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("output\\temp"), file.getPath());
		}

		/**
		 * Tests that double backslashes in filespecs are stripped
		 *  on calls to setOption.
		 *
		 */
		void testStripDoubleBackslashes()
		{

			FileAppender appender;
			appender.setOption(LOG4CXX_STR("FILE"), LOG4CXX_STR("output\\\\temp"));
			const File& file = appender.getFile();
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("output\\temp"), file.getPath());
		}

		/**
		 * Tests stripDuplicateBackslashes
		 *
		 *
		 */
		void testStripDuplicateBackslashes()
		{
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo\\bar\\foo"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\foo\\bar\\foo")));
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo\\bar\\foo\\"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo\\\\bar\\\\foo\\\\")));
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo\\bar\\foo\\"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\foo\\bar\\foo\\")));
			//
			//   UNC's should either start with two backslashes and contain additional singles
			//       or four back slashes and addition doubles
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\\\foo\\bar\\foo"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\\\\\foo\\\\bar\\\\foo")));
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\\\foo\\bar\\foo"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo\\bar\\foo")));
			//
			//   it it starts with doubles but has no other path component
			//      then it is a file path
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo.log"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo.log")));
			//
			//   it it starts with quads but has no other path component
			//      then it is a UNC
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\\\foo.log"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\\\\\foo.log")));
		}

		void testNegativeBufferSizeOptionFallsBack()
		{
			FileAppender appender;
			appender.setOption(LOG4CXX_STR("BUFFERSIZE"), LOG4CXX_STR("-1"));
			LOGUNIT_ASSERT(appender.getBufferSize() >= 0);
		}

		void testOversizedBufferSizeOptionFallsBack()
		{
			FileAppender appender;
			appender.setOption(LOG4CXX_STR("BUFFERSIZE"), LOG4CXX_STR("2G"));
			LOGUNIT_ASSERT(appender.getBufferSize() >= 0);
		}

		void testSetBufferSizeNormalizesNegativeValue()
		{
			FileAppender appender;
			appender.setBufferSize(-100);
			LOGUNIT_ASSERT(appender.getBufferSize() >= 0);
		}

};

LOGUNIT_TEST_SUITE_REGISTRATION(FileAppenderTestCase);
