/**************************************************************
 *
 * 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.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cppu.hxx"

#include "osl/thread.hxx"
#include "osl/conditn.hxx"
#include "osl/mutex.hxx"

#include "cppu/helper/purpenv/Environment.hxx"
#include "cppu/helper/purpenv/Mapping.hxx"


#ifdef debug
# define LOG_LIFECYCLE_AffineBridge
#endif

#ifdef LOG_LIFECYCLE_AffineBridge
#  include <iostream>
#  define LOG_LIFECYCLE_AffineBridge_emit(x) x

#else
#  define LOG_LIFECYCLE_AffineBridge_emit(x)

#endif

class InnerThread;
class OuterThread;

class SAL_DLLPRIVATE AffineBridge : public cppu::Enterable
{
public:
	enum Msg
	{
		CB_DONE,
		CB_FPOINTER
	};

	Msg                   m_message;
	uno_EnvCallee       * m_pCallee;
	va_list             * m_pParam;

	osl::Mutex            m_innerMutex;
	oslThreadIdentifier   m_innerThreadId;
	InnerThread         * m_pInnerThread;
	osl::Condition        m_innerCondition;
	sal_Int32             m_enterCount;

	osl::Mutex            m_outerMutex;
	oslThreadIdentifier   m_outerThreadId;
	osl::Condition        m_outerCondition;
	OuterThread         * m_pOuterThread;

	explicit  AffineBridge(void);
	virtual  ~AffineBridge(void);

	virtual void  v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam);
	virtual void  v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam);

	virtual void  v_enter(void);
	virtual void  v_leave(void);

	virtual int  v_isValid(rtl::OUString * pReason);

	void innerDispatch(void);
	void outerDispatch(int loop);
};

class SAL_DLLPRIVATE InnerThread : public osl::Thread
{
    virtual void SAL_CALL run(void);

	AffineBridge * m_pAffineBridge;

public:
	InnerThread(AffineBridge * threadEnvironment)
		: m_pAffineBridge(threadEnvironment)
		{
			create();
		}
};

void InnerThread::run(void)
{
	m_pAffineBridge->enter();
	m_pAffineBridge->innerDispatch();
	m_pAffineBridge->leave();
}

class SAL_DLLPRIVATE OuterThread : public osl::Thread
{
    virtual void SAL_CALL run(void);

	AffineBridge * m_pAffineBridge;

public:
	OuterThread(AffineBridge * threadEnvironment);
};

OuterThread::OuterThread(AffineBridge * threadEnvironment)
	: m_pAffineBridge(threadEnvironment)
{
	create();
}

void OuterThread::run(void)
{
	osl::MutexGuard guard(m_pAffineBridge->m_outerMutex);

	m_pAffineBridge->m_outerThreadId = getIdentifier();
	m_pAffineBridge->outerDispatch(0);
	m_pAffineBridge->m_outerThreadId = 0;

	m_pAffineBridge->m_pOuterThread = NULL;
	m_pAffineBridge = NULL;
}


AffineBridge::AffineBridge(void)
	: m_innerThreadId(0),
	  m_pInnerThread (NULL),
	  m_enterCount   (0),
	  m_outerThreadId(0),
	  m_pOuterThread (NULL)
{
	LOG_LIFECYCLE_AffineBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "AffineBridge::AffineBridge(uno_Environment * pEnv)", this));
}

AffineBridge::~AffineBridge(void)
{
	LOG_LIFECYCLE_AffineBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "AffineBridge::~AffineBridge(void)", this));

	if (m_pInnerThread && osl_getThreadIdentifier(NULL) != m_innerThreadId)
	{
		m_message = CB_DONE;
		m_innerCondition.set();

		m_pInnerThread->join();
	}

	delete m_pInnerThread;

	if (m_pOuterThread)
	{
		m_pOuterThread->join();
		delete m_pOuterThread;
	}
}


void AffineBridge::outerDispatch(int loop)
{
	OSL_ASSERT(m_outerThreadId == osl_getThreadIdentifier(NULL));
	OSL_ASSERT(m_innerThreadId != m_outerThreadId);

	Msg mm;

	do
	{
		// FIXME: created outer thread must not wait
		// in case of no message
		// note: no message can happen in case newly created
		// outer thread acquire outerMutex after a real outer
		// thread enters outerDispatch!
		m_outerCondition.wait();
		m_outerCondition.reset();

		mm = m_message;

		switch(mm)
		{
		case CB_DONE:
			break;

		case CB_FPOINTER:
		{
			m_pCallee(m_pParam);

			m_message = CB_DONE;
			m_innerCondition.set();
			break;
		}
		default:
			abort();
		}
	}
	while(mm != CB_DONE && loop);
}

void AffineBridge::innerDispatch(void)
{
	OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL));
	OSL_ASSERT(m_innerThreadId != m_outerThreadId);

	Msg mm;

	do
	{
		m_innerCondition.wait();
		m_innerCondition.reset();

		mm = m_message;

		switch(mm)
		{
		case CB_DONE:
			break;

		case CB_FPOINTER:
		{
			m_pCallee(m_pParam);

			m_message = CB_DONE;
			m_outerCondition.set();
			break;
		}
		default:
			abort();
		}
	}
	while(mm != CB_DONE);
}

void AffineBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
{
	osl::MutexGuard guard(m_outerMutex); // only one thread at a time can call into

	if (m_innerThreadId == 0) // no inner thread yet
	{
		m_pInnerThread  = new InnerThread(this);
		m_pInnerThread->resume();
	}

	bool resetId = false;
	if (!m_outerThreadId)
	{
		m_outerThreadId = osl_getThreadIdentifier(NULL);
		resetId = true;
	}

	m_message = CB_FPOINTER;
	m_pCallee = pCallee;
	m_pParam  = pParam;
	m_innerCondition.set();

	outerDispatch(1);

	if (resetId)
		m_outerThreadId = 0;
}

void AffineBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam)
{
	OSL_ASSERT(m_innerThreadId);

	osl::MutexGuard guard(m_innerMutex);

	if (m_outerThreadId == 0) // no outer thread yet
	{
		osl::MutexGuard guard_m_outerMutex(m_outerMutex);

		if (m_outerThreadId == 0)
		{
			if (m_pOuterThread)
			{
				m_pOuterThread->join();
				delete m_pOuterThread;
			}

			m_pOuterThread = new OuterThread(this);
		}
	}

	m_message = CB_FPOINTER;
	m_pCallee = pCallee;
	m_pParam  = pParam;
	m_outerCondition.set();

	innerDispatch();
}

void AffineBridge::v_enter(void)
{
	m_innerMutex.acquire();

	if (!m_enterCount)
		m_innerThreadId = osl_getThreadIdentifier(NULL);

	OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL));

	++ m_enterCount;
}

void AffineBridge::v_leave(void)
{
	OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL));

	-- m_enterCount;
	if (!m_enterCount)
		m_innerThreadId = 0;

	m_innerMutex.release();
}

int  AffineBridge::v_isValid(rtl::OUString * pReason)
{
	int result = 1;

	result = m_enterCount > 0;
	if (!result)
		*pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not entered"));

	else
	{
		result = m_innerThreadId == osl_getThreadIdentifier(NULL);

		if (!result)
			*pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong thread"));
	}

	if (result)
		*pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OK"));

	return result;
}

extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_initEnvironment(uno_Environment * pEnv)
	SAL_THROW_EXTERN_C()
{
    cppu::helper::purpenv::Environment_initWithEnterable(pEnv, new AffineBridge());
}

extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_ext_getMapping(uno_Mapping     ** ppMapping,
														uno_Environment  * pFrom,
														uno_Environment  * pTo )
{
	cppu::helper::purpenv::createMapping(ppMapping, pFrom, pTo);
}
