//..............................................................................
//
// Socket client log filter (TCP Listener, TCP Proxy)
//

import "log_Filter.jnc"
import "PipeServerLogRecordCode.jnc"

//..............................................................................

class PipeClientLogFilter: log.Filter
{
protected:
	bool m_isVisible;
	uint64_t m_filterId;
	uint64_t m_lastVisibleId;

public:
	construct()
	{
		m_filterId = -1;
	}

	// suspend log engine before calling setFilter

	bool errorcode setFilter(char const* filter);

protected:
	override void reset();

	override bool filter(
		uint64_t timestamp,
		uint64_t recordCode,
		void const* p,
		size_t size
		);
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

bool errorcode PipeClientLogFilter.setFilter(char const* filter)
{
	if (!filter)
	{
		m_filterId = -1;
		return true;
	}

	char const* end;
	uint64_t id = strtoul(filter, &end, 0);
	if (end == filter)
	{
		std.setError("invalid pipe client ID");
		return false;
	}

	m_filterId = id;
	return true;
}

void PipeClientLogFilter.reset()
{
	m_isVisible = false;
	m_lastVisibleId = -1;
}

bool PipeClientLogFilter.filter(
	uint64_t timestamp,
	uint64_t recordCode,
	void const* p,
	size_t size
	)
{
	if (m_filterId == -1) // means, filtering is off
		return true;

	switch (recordCode)
	{
	case PipeServerLogRecordCode.ClientConnected:
	case PipeServerLogRecordCode.ClientChanged:
		uint64_t id = *(uint64_t const*)p;
		m_isVisible = id == m_filterId;
		if (!m_isVisible)
			return false;

		if (recordCode == PipeServerLogRecordCode.ClientChanged && id == m_lastVisibleId)
			return false; // don't show unnecessary client-changed messages

		m_lastVisibleId = id;
		return true;

	case PipeServerLogRecordCode.ClientDisconnected:
		uint64_t id = *(uint64_t const*)p;
		bool result = id == m_filterId;
		if (result)
			m_lastVisibleId = -1;

		m_isVisible = false;
		return result;

	default:
		return m_isVisible;
	}
}

//..............................................................................
