#include "fireflierstrings.h"
#include "CResolverThread.h"
#include <arpa/inet.h>
#include <netdb.h>
#if FF_DEBUG
#include <iostream>
using namespace std;
#endif


CResolverThread::CResolverThread()
	: m_bDoRun(true)
	, m_nIP(in_addr_t())
	, m_nIPPrev(in_addr_t())
{
}

	
void CResolverThread::resolve(in_addr_t nIP)
{
	m_sync.lock();
	m_nIP = nIP; // always resolve the last ip address to resolve
	m_sync.unlock();
	if (m_semResolve.getValue() < 1)
		// don't push more than one address to resolve in the "queue"
		m_semResolve.post();
}


void CResolverThread::run()
{
	hostent he;
	hostent* phe(NULL);
	int err(0);
	char buf[1024];
	in_addr addr;
	std::string strHostname;

	while (m_bDoRun)
	{
		m_semResolve.wait();
		m_sync.lock();
		in_addr_t nIP = m_nIP; // make a copy
		m_sync.unlock();
		if (m_bDoRun)
		{
#if FF_DEBUG
			const unsigned char* it = (const unsigned char*) &nIP;
			cout << "Resolving: " << (unsigned short)*it << "." << (unsigned short)*(it+1) << "." << (unsigned short)*(it+2) << "." << (unsigned short)*(it+3) << endl;
#endif
			if (m_nIPPrev != nIP)
			{	// if the current ip differs from the previous one
				m_nIPPrev = nIP;
				addr.s_addr = nIP;
				// thread safe version of gethostbyaddr()
				if (!gethostbyaddr_r(&addr, sizeof(struct in_addr), AF_INET, 
									&he, buf, sizeof(buf), &phe, &err))
				{	// resolved?
#if FF_DEBUG
					const unsigned char* it = (const unsigned char*) &nIP;
					cout << "Resolved: " << (unsigned short)*it << "." << (unsigned short)*(it+1) << "." << (unsigned short)*(it+2) << "." << (unsigned short)*(it+3) << " to " << he.h_name << endl;
#endif
					strHostname = he.h_name;
				}
				else
				{
#if FF_DEBUG
					cout << strNotResolvable << endl;
#endif
					strHostname = strNotResolvable;
				}
			}
#if FF_DEBUG
			else
			{
				const unsigned char* it = (const unsigned char*) &nIP;
				cout << "Resolved: " << (unsigned short)*it << "." << (unsigned short)*(it+1) << "." << (unsigned short)*(it+2) << "." << (unsigned short)*(it+3) << " to " << strHostname << endl;
			}
#endif

			if (m_semResolve.getValue() < 1)
				// don't signal the gui if already the next address is to resolve
				signal_resolved().emit(strHostname.c_str());
		}
	}
}
