/*
 * 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/logstring.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/optionconverter.h>
#include <log4cxx/helpers/pool.h>
#include <log4cxx/helpers/fileoutputstream.h>
#include <log4cxx/helpers/outputstreamwriter.h>
#include <log4cxx/helpers/bufferedwriter.h>
#include <log4cxx/helpers/bytebuffer.h>
#include <log4cxx/private/writerappender_priv.h>
#include <log4cxx/private/fileappender_priv.h>
#include <mutex>

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;
using namespace LOG4CXX_NS::spi;

IMPLEMENT_LOG4CXX_OBJECT(FileAppender)

#define _priv static_cast<FileAppenderPriv*>(m_priv.get())

FileAppender::FileAppender() :
	WriterAppender (std::make_unique<FileAppenderPriv>())
{
}

FileAppender::FileAppender
	( const LayoutPtr& layout1
	, const LogString& fileName1
	, bool append1
	, bool bufferedIO1
	, int bufferSize1
	)
	: WriterAppender(std::make_unique<FileAppenderPriv>(layout1, fileName1, append1, bufferedIO1, bufferSize1))
{
	Pool p;
	activateOptions(p);
}

FileAppender::FileAppender
	( const LayoutPtr& layout1
	, const LogString& fileName1
	, bool append1
	)
	: WriterAppender(std::make_unique<FileAppenderPriv>(layout1, fileName1, append1, false))
{
	Pool p;
	activateOptions(p);
}

FileAppender::FileAppender(const LayoutPtr& layout1, const LogString& fileName1)
	: WriterAppender(std::make_unique<FileAppenderPriv>(layout1, fileName1))
{
	Pool p;
	activateOptions(p);
}

FileAppender::FileAppender(std::unique_ptr<FileAppenderPriv> priv)
	: WriterAppender (std::move(priv))
{
}

FileAppender::~FileAppender()
{
	finalize();
}

void FileAppender::setAppend(bool fileAppend1)
{
	std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
	_priv->fileAppend = fileAppend1;
}

void FileAppender::setFile(const LogString& file)
{
	std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
	setFileInternal(file);
}

void FileAppender::setFileInternal(const LogString& file)
{
	_priv->fileName = file;
}

void FileAppender::setBufferedIO(bool bufferedIO1)
{
	std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
	_priv->bufferedIO = bufferedIO1;

	if (bufferedIO1)
	{
		setImmediateFlush(false);
	}
}

void FileAppender::setOption(const LogString& option,
	const LogString& value)
{
	if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("FILE"), LOG4CXX_STR("file"))
		|| StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("FILENAME"), LOG4CXX_STR("filename")))
	{
		std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
		_priv->fileName = stripDuplicateBackslashes(value);
	}
	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("APPEND"), LOG4CXX_STR("append")))
	{
		std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
		_priv->fileAppend = OptionConverter::toBoolean(value, true);
	}
	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("BUFFEREDIO"), LOG4CXX_STR("bufferedio")))
	{
		std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
		_priv->bufferedIO = OptionConverter::toBoolean(value, false);
	}
	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("IMMEDIATEFLUSH"), LOG4CXX_STR("immediateflush")))
	{
		std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
		_priv->bufferedIO = !OptionConverter::toBoolean(value, false);
	}
	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("BUFFERSIZE"), LOG4CXX_STR("buffersize")))
	{
		std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
		_priv->bufferSize = OptionConverter::toFileSize(value, 8 * 1024);
	}
	else
	{
		WriterAppender::setOption(option, value);
	}
}

void FileAppender::activateOptions(Pool& p)
{
	std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
	activateOptionsInternal(p);
}

void FileAppender::activateOptionsInternal(Pool& p)
{
	int errors = 0;

	if (!_priv->fileName.empty())
	{
		try
		{
			setFileInternal(_priv->fileName, _priv->fileAppend, _priv->bufferedIO, _priv->bufferSize, p);
		}
		catch (IOException& e)
		{
			errors++;
			LogString msg(LOG4CXX_STR("setFile("));
			msg.append(_priv->fileName);
			msg.append(1, (logchar) 0x2C /* ',' */);
			StringHelper::toString(_priv->fileAppend, msg);
			msg.append(LOG4CXX_STR(") call failed."));
			_priv->errorHandler->error(msg, e, ErrorCode::FILE_OPEN_FAILURE);
		}
	}
	else
	{
		errors++;
		LogLog::error(LogString(LOG4CXX_STR("File option not set for appender ["))
			+  _priv->name + LOG4CXX_STR("]."));
		LogLog::warn(LOG4CXX_STR("Are you using FileAppender instead of ConsoleAppender?"));
	}

	if (errors == 0)
	{
		WriterAppender::activateOptions(p);
	}
}


/**
 * Replaces double backslashes (except the leading doubles of UNC's)
 * with single backslashes for compatibility with existing path
 * specifications that were working around use of
 * OptionConverter::convertSpecialChars in XML configuration files.
 *
 * @param src source string
 * @return modified string
 *
 *
 */
LogString FileAppender::stripDuplicateBackslashes(const LogString& src)
{
	logchar backslash = 0x5C; // '\\'
	LogString::size_type i = src.find_last_of(backslash);

	if (i != LogString::npos)
	{
		LogString tmp(src);

		for (;
			i != LogString::npos && i > 0;
			i = tmp.find_last_of(backslash, i - 1))
		{
			//
			//   if the preceding character is a slash then
			//      remove the preceding character
			//      and continue processing
			if (tmp[i - 1] == backslash)
			{
				tmp.erase(i, 1);
				i--;

				if (i == 0)
				{
					break;
				}
			}
			else
			{
				//
				//  if there an odd number of slashes
				//     the string wasn't trying to work around
				//     OptionConverter::convertSpecialChars
				return src;
			}
		}

		return tmp;
	}

	return src;
}

/**
  <p>Sets and <i>opens</i> the file where the log output will
  go. The specified file must be writable.

  <p>If there was already an opened file, then the previous file
  is closed first.

  <p><b>Do not use this method directly. To configure a FileAppender
  or one of its subclasses, set its properties one by one and then
  call activateOptions.</b>

  @param filename The path to the log file.
  @param append   If true will append to fileName. Otherwise will
      truncate fileName.
  @param bufferedIO
  @param bufferSize

  @throws IOException

 */
void FileAppender::setFileInternal(
	const LogString& filename,
	bool append1,
	bool bufferedIO1,
	size_t bufferSize1,
	Pool& p)
{
	// It does not make sense to have immediate flush and bufferedIO.
	if (bufferedIO1)
	{
		setImmediateFlush(false);
	}

	closeWriter();

	bool writeBOM = false;

	if (StringHelper::equalsIgnoreCase(getEncoding(),
			LOG4CXX_STR("utf-16"), LOG4CXX_STR("UTF-16")))
	{
		//
		//    don't want to write a byte order mark if the file exists
		//
		if (append1)
		{
			File outFile(filename);
			writeBOM = !exists(p, outFile);
		}
		else
		{
			writeBOM = true;
		}
	}

	OutputStreamPtr outStream;

	try
	{
		outStream = FileOutputStreamPtr(new FileOutputStream(filename, append1));
	}
	catch (IOException&)
	{
		auto parentName = getParent(p, File(filename));
		if (!parentName.empty())
		{
			File parentDir(parentName);
			if (!exists(p, parentDir) && mkdirs(p, parentDir))
			{
				outStream = OutputStreamPtr(new FileOutputStream(filename, append1));
			}
			else
			{
				throw;
			}
		}
		else
		{
			throw;
		}
	}


	//
	//   if a new file and UTF-16, then write a BOM
	//
	if (writeBOM)
	{
		char bom[] = { (char) 0xFE, (char) 0xFF };
		ByteBuffer buf(bom, 2);
		outStream->write(buf, p);
	}

	WriterPtr newWriter(createWriter(outStream));

	if (bufferedIO1)
	{
		newWriter = std::make_shared<BufferedWriter>(newWriter, bufferSize1);
	}

	setWriterInternal(newWriter);

	_priv->fileAppend = append1;
	_priv->bufferedIO = bufferedIO1;
	_priv->fileName = filename;
	_priv->bufferSize = (int)bufferSize1;
	writeHeader(p);

}

LogString FileAppender::getFile() const
{
	return _priv->fileName;
}

bool FileAppender::getBufferedIO() const
{
	return _priv->bufferedIO;
}

int FileAppender::getBufferSize() const
{
	return _priv->bufferSize;
}

void FileAppender::setBufferSize(int bufferSize1)
{
	_priv->bufferSize = bufferSize1;
}

bool FileAppender::getAppend() const
{
	return _priv->fileAppend;
}
