//..............................................................................
//
// TCP Monitor log representer
//

import "log_Representation.jnc"
import "io_base.jncx"
import "io_SocketAddress.jnc"
import "TcpFlowLogRecordCode.jnc"

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

bool representTcpFlowLog(
	log.Representation* representation,
	uint64_t recordCode,
	void const* p,
	size_t size,
	uint_t foldFlags
) {
	switch (recordCode) {
	case TcpFlowLogRecordCode.Connecting:
		string_t srcAddressString = ((io.SocketAddress const*)p).getString();
		string_t dstAddressString = ((io.SocketAddress const*)p + 1).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText(TcpFlowLogPartCode.Connecting, $"Connecting to \e[34m$dstAddressString\e[m from \e[34m$srcAddressString\e[m...");
		break;

	case TcpFlowLogRecordCode.ConnectCompleted:
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Connect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Connect;
		representation.addHyperText(TcpFlowLogPartCode.ConnectCompleted, "ok");
		break;

	case TcpFlowLogRecordCode.ConnectionPickedUp:
		io.SocketAddress const* serverAddress = (io.SocketAddress const*)p;
		io.SocketAddress const* clientAddress = serverAddress + 1;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Connect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;

		representation.addHyperText(
			$"Picked up connection between \e[34m$(clientAddress.getString())\e[m and "
			$"\e[34m$(serverAddress.getString())"
		);
		break;

	case TcpFlowLogRecordCode.Disconnected_old:
		string_t addressString = ((io.SocketAddress const*)p).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Disconnect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Disconnect;
		representation.addHyperText($"Disconnected by \e[34m$addressString");
		break;

	case TcpFlowLogRecordCode.ConnectionChanged:
		io.SocketAddress const* serverAddress = (io.SocketAddress const*)p;
		io.SocketAddress const* clientAddress = serverAddress + 1;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;

		representation.addHyperText(
			$"Connection between \e[34m$(clientAddress.getString())\e[m and "
			$"\e[34m$(serverAddress.getString())\e[m:"
		);
		break;

	case TcpFlowLogRecordCode.Disconnected:
	case TcpFlowLogRecordCode.Reset:
		io.SocketAddress const* remoteAddress = (io.SocketAddress const*)p;
		io.SocketAddress const* localAddress = remoteAddress + 1;
		string_t closeKindString = recordCode == TcpFlowLogRecordCode.Reset ? "reset" : "closed";
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Disconnect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Disconnect;

		representation.addHyperText(
			$"Disconnected from \e[34m$(remoteAddress.getString())\e[m "
			$"($closeKindString by \e[34m$(localAddress.getString())\e[m)"
		);
		break;

	case TcpFlowLogRecordCode.OutOfOrderDataDropped:
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Warning;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Error;
		representation.addHyperText($"Out-of-order segment(s), data dropped\e");
		break;

	case TcpFlowLogRecordCode.DataLost:
		uint32_t lostSize = *(uint32_t const*)p;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Warning;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Error;
		representation.addHyperText($"Missing TCP segment(s), data lost ($lostSize bytes)\e");
		break;

	case TcpFlowLogRecordCode.TotalDataLost:
		uint32_t txLostSize = *(uint32_t const*)p;
		uint32_t rxLostSize = *((uint32_t const*)p + 1);
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Warning;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Warning;
		representation.addHyperText($"Total data loss: TX $txLostSize bytes; RX $rxLostSize bytes\e");
		break;

	default:
		return false;
	}

	return true;
}

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