//.............................................................................
//
// UDP Flow Monitor log record declarations and representer
//

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

enum UdpFlowMonLogRecordCode
{
	Resolving,
	ResolveCompleted,
	ResolveCancelled,
	ResolveError,
	StartingCapture,
	CaptureStarted,
	CaptureError,
	CaptureStopped,
	ChangingFilter,
	FilterChanged,
	FilterError,
	TxPacket,
	RxPacket,
}

enum UdpFlowMonLogPartCode
{
	Resolving        = 1 | log.PartCodeFlags.MergeableForward,
	ResolveCompleted = 1 | log.PartCodeFlags.MergeableBackward,
	StartingCapture  = 2 | log.PartCodeFlags.MergeableForward,
	CaptureCompleted = 2 | log.PartCodeFlags.MergeableBackward,
	ChangingFilter   = 3 | log.PartCodeFlags.MergeableForward,
	FilterCompleted  = 3 | log.PartCodeFlags.MergeableBackward,
}

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

struct UdpFlowMonPacketParams
{
	io.SocketAddress m_srcAddress;
	io.SocketAddress m_dstAddress;
	uint32_t m_size;
	bool m_isFragmented;
}

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

bool representUdpFlowMonLog (
	log.RepresenterTarget* target,
	uint_t recordCode,
	void const* p,
	size_t size,
	uint_t foldFlags
	)
{
	switch (recordCode)
	{
	case UdpFlowMonLogRecordCode.Resolving:
		char const* addressString = (char const*) p;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		target.m_lineAttr.m_backColor = log.StdLogColor.Info;
		target.addHyperText (UdpFlowMonLogPartCode.Resolving, $"Resolving \e[34m$addressString\e[m...");
		break;

	case UdpFlowMonLogRecordCode.ResolveCompleted:		
		char const* addressString = ((io.SocketAddress const*) p).getString ();
		target.addHyperText (UdpFlowMonLogPartCode.ResolveCompleted, $"ok (\e[34m$addressString\e[m)");
		break;

	case UdpFlowMonLogRecordCode.ResolveCancelled:		
		target.addPlainText (UdpFlowMonLogPartCode.ResolveCompleted, "cancelled");
		break;

	case UdpFlowMonLogRecordCode.ResolveError:
		std.Error const* error = (std.Error const*) p;
		target.m_lineAttr.m_flags = log.LineAttrFlags.Override;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Error;
		target.m_lineAttr.m_backColor = log.StdLogColor.Error;
		target.addPlainText (UdpFlowMonLogPartCode.ResolveCompleted, $"error: $(error.m_description)");
		break;
		
	case UdpFlowMonLogRecordCode.StartingCapture:
		char const* filter = (char const*) p;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		target.m_lineAttr.m_backColor = log.StdLogColor.Info;
		target.addHyperText (UdpFlowMonLogPartCode.StartingCapture, $"Starting capture with filter \e[34m$filter\e[m...");
		break;

	case UdpFlowMonLogRecordCode.CaptureStarted:
		target.m_lineAttr.m_flags = log.LineAttrFlags.Override;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Listen;
		target.m_lineAttr.m_backColor = log.StdLogColor.Connect;
		target.addPlainText (UdpFlowMonLogPartCode.CaptureCompleted, "ok");
		break;

	case UdpFlowMonLogRecordCode.CaptureError:
		std.Error const* error = (std.Error const*) p;
		target.m_lineAttr.m_flags = log.LineAttrFlags.Override;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Error;
		target.m_lineAttr.m_backColor = log.StdLogColor.Error;
		target.addPlainText (UdpFlowMonLogPartCode.CaptureCompleted, $"error ($(error.m_description))");
		break;

	case UdpFlowMonLogRecordCode.CaptureStopped:
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.StopListen;
		target.m_lineAttr.m_backColor = log.StdLogColor.Disconnect;
		target.addPlainText ("Capture stopped");
		break;

	case UdpFlowMonLogRecordCode.ChangingFilter:
		char const* filter = (char const*) p;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		target.m_lineAttr.m_backColor = log.StdLogColor.Info;
		target.addHyperText (UdpFlowMonLogPartCode.ChangingFilter, $"Changing capture filter to \e[34m$filter\e[m...");
		break;

	case UdpFlowMonLogRecordCode.FilterChanged:
		target.addPlainText (UdpFlowMonLogPartCode.FilterCompleted, "ok");
		break;

	case UdpFlowMonLogRecordCode.FilterError:
		std.Error const* error = (std.Error const*) p;
		target.m_lineAttr.m_flags = log.LineAttrFlags.Override;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Error;
		target.m_lineAttr.m_backColor = log.StdLogColor.Error;
		target.addPlainText (UdpFlowMonLogPartCode.FilterCompleted, $"error ($(error.m_description))");
		break;

	case UdpFlowMonLogRecordCode.TxPacket:
	case UdpFlowMonLogRecordCode.RxPacket:		
		UdpFlowMonPacketParams const* params = (UdpFlowMonPacketParams const*) p;
		
		target.m_lineAttr.m_iconIdx = recordCode == UdpFlowMonLogRecordCode.TxPacket ?
			log.StdLogIcon.TxPacket :
			log.StdLogIcon.RxPacket;
		target.m_lineAttr.m_backColor = gui.StdColor.PastelGray;
		
		char const* text = $"From \e[34m%1\e[m to \e[34m%2\e[m (%3 B)" (
			params.m_srcAddress.getString (),
			params.m_dstAddress.getString (),
			params.m_size			
			);
			
		if (params.m_isFragmented)
			text = $"$text \e[31mfragmented";
		
		target.addHyperText (text);
		break;

	default:
		return false;
	}

	return true;
}

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