//..............................................................................
//
// Mailslot Monitor log filter
//

import "log_MonitorFilter.jnc"

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

class MailslotMonLogFilter: log.MonitorFilter {
public:
	override bool filter(
		uint64_t timestamp,
		uint64_t recordCode,
		void const* p,
		size_t size
	);
}

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

bool MailslotMonLogFilter.filter(
	uint64_t timestamp,
	uint64_t recordCode,
	void const* p,
	size_t size
) {
	bool result = false;

	switch (recordCode) {
	case MailslotMonLogRecordCode.ServerFileOpened_0:
	case MailslotMonLogRecordCode.ClientFileOpened_0:
		m_fileId = *(uint32_t const*)p;
		string_t fileName = (char const*)(p + sizeof(uint32_t));
		result = match(fileName, null, 0, true);
		break;

	case MailslotMonLogRecordCode.ServerFileOpened_1:
	case MailslotMonLogRecordCode.ClientFileOpened_1:
		m_fileId = *(uint32_t const*)p;
		uint_t pid = *(uint32_t const*)(p + sizeof(uint32_t));
		string_t fileName = (char const*)(p + sizeof(uint32_t) + sizeof(uint32_t));
		result = match(fileName, null, pid, true);
		break;

	case MailslotMonLogRecordCode.ServerFileOpened:
	case MailslotMonLogRecordCode.ClientFileOpened:
		m_fileId = *(uint64_t const*)p;
		uint_t pid = *(uint32_t const*)(p + sizeof(uint64_t));
		string_t fileName = (char const*)(p + sizeof(uint64_t) + sizeof(uint32_t));
		string_t processName = fileName.m_p + fileName.m_length + 1;
		result = match(fileName, processName, pid, true);
		break;

	case MailslotMonLogRecordCode.ServerFileOpenError_0:
	case MailslotMonLogRecordCode.ClientFileOpenError_0:
		std.Error const* error = (std.Error const*)p;
		string_t fileName = (char const*)(error + 1);
		result = match(fileName, null, 0, false);
		break;

	case MailslotMonLogRecordCode.ServerFileOpenError_1:
	case MailslotMonLogRecordCode.ClientFileOpenError_1:
		uint_t pid = *(uint32_t const*)p;
		std.Error const* error = (std.Error const*)(p + sizeof(uint32_t));
		string_t fileName = (char const*)(error + 1);
		result = match(fileName, null, pid, false);
		break;

	case MailslotMonLogRecordCode.ServerFileOpenError:
	case MailslotMonLogRecordCode.ClientFileOpenError:
		uint_t pid = *(uint32_t const*)p;
		std.Error const* error = (std.Error const*)(p + sizeof(uint32_t));
		string_t fileName = (char const*)(error + 1);
		string_t processName = fileName.m_p + fileName.m_length + 1;
		result = match(fileName, processName, pid, false);
		break;

	case MailslotMonLogRecordCode.FileClosed:
		result = m_fileIdSet.removeKey(m_fileId);
		break;

	case MailslotMonLogRecordCode.FileIdChanged_0:
	case MailslotMonLogRecordCode.FileIdChanged_1:
		m_fileId = *(uint32_t const*)p;
		if (m_fileId == m_lastVisibleFileId)
			return false; // no need to show extra file-id-changed message

		break;

	case MailslotMonLogRecordCode.FileIdChanged:
		m_fileId = *(uint64_t const*)p;
		if (m_fileId == m_lastVisibleFileId)
			return false; // no need to show extra file-id-changed message

		break;

	case log.StdRecordCode.Tx:
	case log.StdRecordCode.Rx:
		break;

	default:
		return true; // everything else is not filtered
	}

	return finalizeFilter(result);
}

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