/*
 * 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/log4cxx.h>
#include <log4cxx/logstring.h>
#include <log4cxx/helpers/threadspecificdata.h>
#include <log4cxx/helpers/exception.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/transcoder.h>
#include <apr_thread_proc.h>
#include <apr_strings.h>
#if !defined(LOG4CXX)
	#define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>
#include <log4cxx/helpers/aprinitializer.h>
#include <sstream>
#include <algorithm>
#include <thread>
#include <mutex>
#include <list>

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;

struct ThreadSpecificData::ThreadSpecificDataPrivate{
	ThreadSpecificDataPrivate()
		: pNamePair(std::make_shared<NamePair>())
	{
		setThreadIdName();
		setThreadUserName();
	}
	NDC::Stack ndcStack;
	MDC::Map mdcMap;

	std::shared_ptr<NamePair> pNamePair;

	template <typename T>
	struct CountedStringStream
	{
		int usage_count{ 0 };
		std::basic_ostringstream<T> ss;
	};

	// Find an unused stream buffer or add a new stream buffer in the collection \c store
	template <typename T>
	std::basic_ostringstream<T>& getStream(std::list<CountedStringStream<T> >& store)
	{
		CountedStringStream<T>* pItem{ nullptr };
		for (auto& item : store)
		{
			if (0 == item.usage_count)
			{
				pItem = &item;
				break;
			}
		}
		if (!pItem)
		{
			store.emplace_back();
			pItem = &store.back();
		}
		++pItem->usage_count;
		return pItem->ss;
	}

	// Decrement the usage count associated with the stream buffer \c ss in the collection \c store
	template <typename T>
	void releaseStream(std::list<CountedStringStream<T> >& store, std::basic_ostringstream<T>& ss)
	{
		for (auto& item : store)
		{
			if (&item.ss == &ss)
			{
				--item.usage_count;
				break;
			}
		}
	}

	std::list<CountedStringStream<char> > char_stringstream;

#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
	std::list<CountedStringStream<wchar_t> > wchar_stringstream;
#endif

	void setThreadIdName();
	void setThreadUserName();
};

/* Generate an identifier for the current thread
*/
void ThreadSpecificData::ThreadSpecificDataPrivate::setThreadIdName()
{
#if LOG4CXX_HAS_PTHREAD_SELF && !(defined(_WIN32) && defined(_LIBCPP_VERSION))
	// pthread_t encoded in HEX takes needs as many characters
	// as two times the size of the type, plus an additional null byte.
	auto threadId = pthread_self();
	char result[sizeof(pthread_t) * 3 + 10];
	apr_snprintf(result, sizeof(result), LOG4CXX_APR_THREAD_FMTSPEC, (void*) &threadId);
	this->pNamePair->idString = Transcoder::decode(result);
#elif defined(_WIN32)
	char result[20];
	apr_snprintf(result, sizeof(result), LOG4CXX_WIN32_THREAD_FMTSPEC, GetCurrentThreadId());
	this->pNamePair->idString = Transcoder::decode(result);
#else
	std::stringstream ss;
	ss << std::hex << "0x" << std::this_thread::get_id();
	this->pNamePair->idString = Transcoder::decode(ss.str().c_str());
#endif
}

/*
 * Get the user-specified name of the current thread (on a per-platform basis).
 * This is set using a method such as pthread_setname_np on POSIX
 * systems or SetThreadDescription on Windows.
 */
void ThreadSpecificData::ThreadSpecificDataPrivate::setThreadUserName()
{
#if LOG4CXX_HAS_PTHREAD_GETNAME && !(defined(_WIN32) && defined(_LIBCPP_VERSION))
	char result[16];
	pthread_t current_thread = pthread_self();
	if (pthread_getname_np(current_thread, result, sizeof(result)) < 0 || 0 == result[0])
		this->pNamePair->threadName = this->pNamePair->idString;
	else
		this->pNamePair->threadName = Transcoder::decode(result);
#elif defined(_WIN32)
	typedef HRESULT (WINAPI *TGetThreadDescription)(HANDLE, PWSTR*);
	static struct initialiser
	{
		HMODULE hKernelBase;
		TGetThreadDescription GetThreadDescription;
		initialiser()
			: hKernelBase(GetModuleHandleA("KernelBase.dll"))
			, GetThreadDescription(nullptr)
		{
			if (hKernelBase)
				GetThreadDescription = reinterpret_cast<TGetThreadDescription>(GetProcAddress(hKernelBase, "GetThreadDescription"));
		}
	} win32func;
	if (win32func.GetThreadDescription)
	{
		PWSTR result = 0;
		HRESULT hr = win32func.GetThreadDescription(GetCurrentThread(), &result);
		if (SUCCEEDED(hr) && result)
		{
			std::wstring wresult = result;
			LOG4CXX_DECODE_WCHAR(decoded, wresult);
			LocalFree(result);
			this->pNamePair->threadName = decoded;
		}
	}
	if (this->pNamePair->threadName.empty())
		this->pNamePair->threadName = this->pNamePair->idString;
#else
	this->pNamePair->threadName = this->pNamePair->idString;
#endif
}

ThreadSpecificData::ThreadSpecificData()
	: m_priv(std::make_unique<ThreadSpecificDataPrivate>())
{
}

ThreadSpecificData::ThreadSpecificData(ThreadSpecificData&& other)
	: m_priv(std::move(other.m_priv))
{
}

ThreadSpecificData::~ThreadSpecificData()
{
	m_priv.reset();
}

NDC::Stack& ThreadSpecificData::getStack()
{
	return m_priv->ndcStack;
}

MDC::Map& ThreadSpecificData::getMap()
{
	return m_priv->mdcMap;
}

auto ThreadSpecificData::getNames() -> NamePairPtr
{
	auto p = getCurrentData();
	return p ? p->m_priv->pNamePair : std::make_shared<NamePair>();
}

std::basic_ostringstream<char>& ThreadSpecificData::getStream(const char&)
{
	auto p = getCurrentData();
	return p->m_priv->getStream(p->m_priv->char_stringstream);
}

void ThreadSpecificData::releaseStream(std::basic_ostringstream<char>& ss)
{
	auto p = getCurrentData();
	p->m_priv->releaseStream(p->m_priv->char_stringstream, ss);
}

#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
std::basic_ostringstream<wchar_t>& ThreadSpecificData::getStream(const wchar_t&)
{
	auto p = getCurrentData();
	return p->m_priv->getStream(p->m_priv->wchar_stringstream);
}

void ThreadSpecificData::releaseStream(std::basic_ostringstream<wchar_t>& ss)
{
	auto p = getCurrentData();
	p->m_priv->releaseStream(p->m_priv->wchar_stringstream, ss);
}
#endif


ThreadSpecificData* ThreadSpecificData::getCurrentData()
{
#if LOG4CXX_HAS_THREAD_LOCAL
	thread_local ThreadSpecificData data;
	return data.m_priv ? &data : NULL;
#elif APR_HAS_THREADS
	void* pData = NULL;
	if (APR_SUCCESS == apr_threadkey_private_get(&pData, APRInitializer::getTlsKey())
		&& !pData)
	{
		pData = new ThreadSpecificData();
		if (APR_SUCCESS != apr_threadkey_private_set(pData, APRInitializer::getTlsKey()))
		{
			delete (ThreadSpecificData*)pData;
			pData = NULL;
		}
	}
	if (pData)
		return (ThreadSpecificData*) pData;
#endif

#if !LOG4CXX_HAS_THREAD_LOCAL
	// Fallback implementation that is not expected to be used
	using TaggedData = std::pair<std::thread::id, ThreadSpecificData>;
	static std::list<TaggedData> thread_id_map;
	static std::mutex mutex;
	std::lock_guard<std::mutex> lock(mutex);
	auto threadId = std::this_thread::get_id();
	auto pThreadId = std::find_if(thread_id_map.begin(), thread_id_map.end()
		, [threadId](const TaggedData& item) { return threadId == item.first; });
	if (thread_id_map.end() == pThreadId)
		pThreadId = thread_id_map.emplace(thread_id_map.begin(), threadId, ThreadSpecificData());
	return &pThreadId->second;
#endif
}

void ThreadSpecificData::recycle()
{
#if !LOG4CXX_HAS_THREAD_LOCAL && APR_HAS_THREADS
	if (m_priv->ndcStack.empty() && m_priv->mdcMap.empty())
	{
		void* pData = NULL;
		if (APR_SUCCESS == apr_threadkey_private_get(&pData, APRInitializer::getTlsKey())
			&& pData == this
			&& APR_SUCCESS == apr_threadkey_private_set(0, APRInitializer::getTlsKey()))
				delete this;
	}
#endif
}

void ThreadSpecificData::put(const LogString& key, const LogString& val)
{
	if (auto p = getCurrentData())
		p->getMap()[key] = val;
}

void ThreadSpecificData::push(const LogString& val)
{
	auto p = getCurrentData();
	if (!p)
		return;
	NDC::Stack& stack = p->getStack();
	if (stack.empty())
	{
		stack.push(NDC::DiagnosticContext(val, val));
	}
	else
	{
		LogString fullMessage(stack.top().second);
		fullMessage.append(1, (logchar) 0x20);
		fullMessage.append(val);
		stack.push(NDC::DiagnosticContext(val, fullMessage));
	}
}

void ThreadSpecificData::inherit(const NDC::Stack& src)
{
	if (auto p = getCurrentData())
		p->getStack() = src;
}

