/*
 * 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 <apr_file_io.h>
#include <apr_file_info.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/pool.h>

namespace LOG4CXX_NS
{

template<class S>
static LogString decodeLS(const S* src)
{
	LogString dst;

	if (src != 0)
	{
		helpers::Transcoder::decode(src, dst);
	}

	return dst;
}

template<class S>
static LogString decodeLS(const std::basic_string<S>& src)
{
	LogString dst;
	helpers::Transcoder::decode(src, dst);
	return dst;
}

char* getPath(helpers::Pool& p, const File& f)
{
	int style = APR_FILEPATH_ENCODING_UNKNOWN;
	apr_filepath_encoding(&style, p.getAPRPool());
	char* retval = NULL;

	if (style == APR_FILEPATH_ENCODING_UTF8)
	{
		retval = helpers::Transcoder::encodeUTF8(getPath(f), p);
	}
	else
	{
		retval = helpers::Transcoder::encode(getPath(f), p);
	}

	return retval;
}

char* convertBackSlashes(char* src)
{
	for (char* c = src; *c != 0; c++)
	{
		if (*c == '\\')
		{
			*c = '/';
		}
	}

	return src;
}

std::vector<LogString> getFileList(helpers::Pool& p, const File& dir)
{
	apr_dir_t* pDir;
	apr_finfo_t entry;
	std::vector<LogString> filenames;

	apr_status_t stat = apr_dir_open(&pDir,
			convertBackSlashes(getPath(p, dir)),
			p.getAPRPool());

	if (stat == APR_SUCCESS)
	{
		int style = APR_FILEPATH_ENCODING_UNKNOWN;
		apr_filepath_encoding(&style, p.getAPRPool());
		stat = apr_dir_read(&entry, APR_FINFO_DIRENT, pDir);

		while (stat == APR_SUCCESS)
		{
			if (entry.name != NULL)
			{
				LogString filename;

				if (style == APR_FILEPATH_ENCODING_UTF8)
				{
					helpers::Transcoder::decodeUTF8(entry.name, filename);
				}
				else
				{
					helpers::Transcoder::decode(entry.name, filename);
				}

				filenames.push_back(filename);
			}

			stat = apr_dir_read(&entry, APR_FINFO_DIRENT, pDir);
		}

		stat = apr_dir_close(pDir);
	}

	return filenames;
}

} // namespace LOG4CXX_NS

#if LOG4CXX_FILE_IS_FILESYSTEM_PATH

namespace LOG4CXX_NS
{

bool deleteFile(helpers::Pool&, const File& f)
{
	FileErrorCode ec;
	return remove(f, ec);
}

LogString getPath(const File& f)
{
#if LOG4CXX_LOGCHAR_IS_UTF8
	return f.string();
#elif LOG4CXX_LOGCHAR_IS_WCHAR_T
	return f.wstring();
#else
	return decodeLS(f.wstring());
#endif
}

LogString getParent(helpers::Pool&, const File& f)
{
	LogString result;
	if (f.has_parent_path())
		result = getPath(f.parent_path());
	return result;
}

log4cxx_time_t lastModified(helpers::Pool&, const File& f)
{
	log4cxx_time_t result = 0;
	FileErrorCode ec;
	auto ftime = last_write_time(f, ec);
	if (!ec)
	{
		result = std::chrono::system_clock::to_time_t(clock_cast<std::chrono::system_clock>(ftime));
	}
	return result;
}

size_t length(helpers::Pool&, const File& f)
{
	size_t result = 0;
	FileErrorCode ec;
	auto fsize = file_size(f, ec);
	if (!ec)
	{
		result = static_cast<size_t>(fsize);
	}
	return result;
}

bool mkdirs(helpers::Pool&, const File& f)
{
	FileErrorCode ec;
	return create_directories(f, ec);
}

log4cxx_status_t openFile(const File& f, apr_file_t** file, int flags, int perm, helpers::Pool& p)
{
	return apr_file_open(file, getPath(p, f), flags, perm, p.getAPRPool());
}

} // namespace LOG4CXX_NS

#else // !LOG4CXX_FILE_IS_FILESYSTEM_PATH
#include <assert.h>
#include <log4cxx/helpers/exception.h>

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;

struct File::FilePrivate{
	FilePrivate() :
		autoDelete(false)
	{}

	FilePrivate(LogString path) :
		path(path),
		autoDelete(false)
	{}

	FilePrivate(LogString path, bool autoDelete) :
		path(path),
		autoDelete(autoDelete)
	{}

	LogString path;
	bool autoDelete;
};

File::File() :
	m_priv(std::make_unique<FilePrivate>())
{
}

File::File(const std::string& name)
#if LOG4CXX_LOGCHAR_IS_UTF8
	: m_priv(std::make_unique<FilePrivate>(name))
#else
	: m_priv(std::make_unique<FilePrivate>(decodeLS(name)))
#endif
{
}

File::File(const char* name)
#if LOG4CXX_LOGCHAR_IS_UTF8
	: m_priv(std::make_unique<FilePrivate>(name))
#else
	: m_priv(std::make_unique<FilePrivate>(decodeLS(name)))
#endif
{
}

#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR_T
File::File(const std::wstring& name)
#if LOG4CXX_LOGCHAR_IS_WCHAR_T
	: m_priv(std::make_unique<FilePrivate>(name))
#else
	: m_priv(std::make_unique<FilePrivate>(decodeLS(name)))
#endif
{
}

File::File(const wchar_t* name1)
#if LOG4CXX_LOGCHAR_IS_WCHAR_T
	: m_priv(std::make_unique<FilePrivate>(name))
#else
	: m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
#endif
{
}
#endif

#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
File::File(const std::basic_string<UniChar>& name1)
	: m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
{
}

File::File(const UniChar* name1)
	: m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
{
}
#endif

#if LOG4CXX_CFSTRING_API
File::File(const CFStringRef& name1)
	: m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
{
}
#endif

File::File(const File& src)
	: m_priv(std::make_unique<FilePrivate>(src.m_priv->path, src.m_priv->autoDelete))
{
}

File& File::operator=(const File& src)
{
	if (this == &src)
	{
		return *this;
	}

	m_priv->path.assign(src.m_priv->path);
	m_priv->autoDelete = src.m_priv->autoDelete;

	return *this;
}

File& File::operator=(const LogString& newName)
{
	m_priv->path.assign(newName);
	return *this;
}


File::~File()
{
	if(m_priv->autoDelete){
		Pool p;
		deleteFile(p);
	}
}


LogString File::getPath() const
{
	return m_priv->path;
}

File& File::setPath(const LogString& newName)
{
	m_priv->path.assign(newName);
	return *this;
}

LogString File::getName() const
{
	const logchar slashes[] = { 0x2F, 0x5C, 0 };
	size_t lastSlash = m_priv->path.find_last_of(slashes);

	if (lastSlash != LogString::npos)
	{
		return m_priv->path.substr(lastSlash + 1);
	}

	return m_priv->path;
}

char* File::getPath(Pool& p) const
{
	return ::getPath(p, *this);
}

log4cxx_status_t File::open(apr_file_t** file, int flags,
	int perm, Pool& p) const
{
	return apr_file_open(file, getPath(p), flags, perm, p.getAPRPool());
}



bool File::exists(Pool& p) const
{
	apr_finfo_t finfo;
	apr_status_t rv = apr_stat(&finfo, getPath(p),
			0, p.getAPRPool());
	return rv == APR_SUCCESS;
}

char* File::convertBackSlashes(char* src)
{
	for (char* c = src; *c != 0; c++)
	{
		if (*c == '\\')
		{
			*c = '/';
		}
	}

	return src;
}

bool File::deleteFile(Pool& p) const
{
	apr_status_t rv = apr_file_remove(convertBackSlashes(getPath(p)),
			p.getAPRPool());
	return rv == APR_SUCCESS;
}

bool File::renameTo(const File& dest, Pool& p) const
{
	apr_status_t rv = apr_file_rename(convertBackSlashes(getPath(p)),
			convertBackSlashes(dest.getPath(p)),
			p.getAPRPool());
	return rv == APR_SUCCESS;
}


size_t File::length(Pool& pool) const
{
	apr_finfo_t finfo;
	apr_status_t rv = apr_stat(&finfo, getPath(pool),
			APR_FINFO_SIZE, pool.getAPRPool());

	if (rv == APR_SUCCESS)
	{
		return (size_t) finfo.size;
	}

	return 0;
}


log4cxx_time_t File::lastModified(Pool& pool) const
{
	apr_finfo_t finfo;
	apr_status_t rv = apr_stat(&finfo, getPath(pool),
			APR_FINFO_MTIME, pool.getAPRPool());

	if (rv == APR_SUCCESS)
	{
		return finfo.mtime;
	}

	return 0;
}


std::vector<LogString> File::list(Pool& p) const
{
	return getFileList(p, *this);
}
LogString File::getParent(Pool&) const
{
	LogString::size_type slashPos = m_priv->path.rfind(LOG4CXX_STR('/'));
	LogString::size_type backPos = m_priv->path.rfind(LOG4CXX_STR('\\'));

	if (slashPos == LogString::npos)
	{
		slashPos = backPos;
	}
	else
	{
		if (backPos != LogString::npos && backPos > slashPos)
		{
			slashPos = backPos;
		}
	}

	LogString parent;

	if (slashPos != LogString::npos && slashPos > 0)
	{
		parent.assign(m_priv->path, 0, slashPos);
	}

	return parent;
}

bool File::mkdirs(Pool& p) const
{
	apr_status_t stat = apr_dir_make_recursive(convertBackSlashes(getPath(p)),
			APR_OS_DEFAULT, p.getAPRPool());
	return stat == APR_SUCCESS;
}

void File::setAutoDelete(bool autoDelete){
	m_priv->autoDelete = autoDelete;
}

bool File::getAutoDelete() const{
	return m_priv->autoDelete;
}

#endif // !LOG4CXX_FILE_IS_FILESYSTEM_PATH
