/*
 * 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/file.h>
#include "logunit.h"
#include "insertwide.h"
#include <log4cxx/helpers/pool.h>
#include <apr_errno.h>
#include <log4cxx/helpers/exception.h>
#include <log4cxx/helpers/fileinputstream.h>

#include <log4cxx/helpers/outputstreamwriter.h>
#include <log4cxx/helpers/fileoutputstream.h>
#include <log4cxx/helpers/inputstreamreader.h>
#include <log4cxx/helpers/fileinputstream.h>
#include <log4cxx/helpers/loglog.h>

#if LOG4CXX_CFSTRING_API
	#include <CoreFoundation/CFString.h>
#endif

using namespace log4cxx;
using namespace log4cxx::helpers;


LOGUNIT_CLASS(FileTestCase)
{
	LOGUNIT_TEST_SUITE(FileTestCase);
	LOGUNIT_TEST(defaultConstructor);
	LOGUNIT_TEST(defaultExists);
	LOGUNIT_TEST(defaultRead);
	LOGUNIT_TEST(propertyRead);
	LOGUNIT_TEST(propertyExists);
	LOGUNIT_TEST(fileWrite1);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(wcharConstructor);
#endif
#if LOG4CXX_UNICHAR_API
	LOGUNIT_TEST(unicharConstructor);
#endif
#if LOG4CXX_CFSTRING_API
	LOGUNIT_TEST(cfstringConstructor);
#endif
	LOGUNIT_TEST(copyConstructor);
	LOGUNIT_TEST(assignment);
	LOGUNIT_TEST(deleteBackslashedFileName);
	LOGUNIT_TEST_SUITE_END();

#ifdef _DEBUG
	struct Fixture
	{
		Fixture() {
			helpers::LogLog::setInternalDebugging(true);
		}
	} suiteFixture;
#endif

public:
	void defaultConstructor()
	{
		File defFile;
		LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR(""), defFile.getPath());
	}



	void defaultExists()
	{
		File defFile;
		Pool pool;
		bool exists = defFile.exists(pool);
		LOGUNIT_ASSERT_EQUAL(false, exists);
	}

	// check default constructor. read() throws an exception
	// if no file name was given.
	void defaultRead()
	{
		File defFile;
		Pool pool;

		try
		{
			InputStreamPtr defInput = FileInputStreamPtr(new FileInputStream(defFile));
			InputStreamReaderPtr inputReader = InputStreamReaderPtr(new InputStreamReader(defInput));
			LogString contents(inputReader->read(pool));
			LOGUNIT_ASSERT(false);
		}
		catch (IOException& ex)
		{
		}
	}


#if LOG4CXX_WCHAR_T_API
	void wcharConstructor()
	{
		File propFile(L"input/patternLayout1.properties");
		Pool pool;
		bool exists = propFile.exists(pool);
		LOGUNIT_ASSERT_EQUAL(true, exists);
	}
#endif

#if LOG4CXX_UNICHAR_API
	void unicharConstructor()
	{
		const log4cxx::UniChar filename[] = { 'i', 'n', 'p', 'u', 't', '/',
				'p', 'a', 't', 't', 'e', 'r', 'n', 'L', 'a', 'y', 'o', 'u', 't', '1', '.',
				'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's', 0
			};
		File propFile(filename);
		Pool pool;
		bool exists = propFile.exists(pool);
		LOGUNIT_ASSERT_EQUAL(true, exists);
	}
#endif

#if LOG4CXX_CFSTRING_API
	void cfstringConstructor()
	{
		File propFile(CFSTR("input/patternLayout1.properties"));
		Pool pool;
		bool exists = propFile.exists(pool);
		LOGUNIT_ASSERT_EQUAL(true, exists);
	}
#endif

	void copyConstructor()
	{
		File propFile("input/patternLayout1.properties");
		File copy(propFile);
		Pool pool;
		bool exists = copy.exists(pool);
		LOGUNIT_ASSERT_EQUAL(true, exists);
	}

	void assignment()
	{
		File propFile("input/patternLayout1.properties");
		File copy = propFile;
		Pool pool;
		bool exists = copy.exists(pool);
		LOGUNIT_ASSERT_EQUAL(true, exists);
	}

	void propertyRead()
	{
		File propFile("input/patternLayout1.properties");
		Pool pool;
		InputStreamPtr propStream = FileInputStreamPtr(new FileInputStream(propFile));
		InputStreamReaderPtr propReader = InputStreamReaderPtr(new InputStreamReader(propStream));
		LogString props(propReader->read(pool));
		LogString line1(LOG4CXX_STR("# Licensed to the Apache Software Foundation (ASF) under one or more"));
		LOGUNIT_ASSERT_EQUAL(line1, props.substr(0, line1.length()));
	}

	void propertyExists()
	{
		File propFile("input/patternLayout1.properties");
		Pool pool;
		bool exists = propFile.exists(pool);
		LOGUNIT_ASSERT_EQUAL(true, exists);
	}

	void fileWrite1()
	{
		OutputStreamPtr fos = FileOutputStreamPtr(
				new FileOutputStream(LOG4CXX_STR("output/fileWrite1.txt")));
		OutputStreamWriterPtr osw = OutputStreamWriterPtr(new OutputStreamWriter(fos));

		Pool pool;
		LogString greeting(LOG4CXX_STR("Hello, World"));
		greeting.append(LOG4CXX_EOL);
		osw->write(greeting, pool);

		InputStreamPtr is = FileInputStreamPtr(
				new FileInputStream(LOG4CXX_STR("output/fileWrite1.txt")));
		InputStreamReaderPtr isr = InputStreamReaderPtr(new InputStreamReader(is));
		LogString reply = isr->read(pool);

		LOGUNIT_ASSERT_EQUAL(greeting, reply);
	}

	/**
	 *  Tests conversion of backslash containing file names.
	 *  Would cause infinite loop due to bug LOGCXX-105.
	 */
	void deleteBackslashedFileName()
	{
		File file("output\\bogus.txt");
		Pool pool;
		/*bool deleted = */file.deleteFile(pool);
	}
};


LOGUNIT_TEST_SUITE_REGISTRATION(FileTestCase);
