//.............................................................................
//
// TCP Connection log packet declarations and representer
//

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

enum TcpConnectionLogRecordCode
{
	Resolving,
	Connecting,
	ConnectingFrom,
	ResolveCompleted,
	ConnectCompleted,
	ConnectCancelled,
	ConnectError,
	Disconnected,
}

enum TcpConnectionPartCode
{
	Connecting       = 1 | log.PartCodeFlags.MergeableForward,
	ConnectCompleted = 1 | log.PartCodeFlags.MergeableBackward,
}

bitflag enum TcpDisconnectLogRecordFlags
{
	Remote,
	Reset,	
}

struct TcpDisconnectLogRecordParams
{
	io.SocketAddress m_address;
	uint_t m_flags;
}

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

bool representTcpConnectionLog (
	log.RepresenterTarget* target,
	uint_t recordCode,
	void const* p,
	size_t size,
	uint_t foldFlags
	)
{
	switch (recordCode)
	{
	case TcpConnectionLogRecordCode.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 (TcpConnectionPartCode.Connecting, $"Resolving \e[34m$addressString\e[m...");
		break;

	case TcpConnectionLogRecordCode.Connecting:
		char const* addressString = ((io.SocketAddress const*) p).getString ();
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		target.m_lineAttr.m_backColor = log.StdLogColor.Info;
		target.addHyperText (TcpConnectionPartCode.Connecting, $"Connecting to \e[34m$addressString\e[m...");
		break;
		
	case TcpConnectionLogRecordCode.ConnectingFrom:
		char const* remoteAddressString = ((io.SocketAddress const*) p).getString ();
		char const* localAddressString = ((io.SocketAddress const*) p + 1).getString ();
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		target.m_lineAttr.m_backColor = log.StdLogColor.Info;
		target.addHyperText (TcpConnectionPartCode.Connecting, $"Connecting to \e[34m$remoteAddressString\e[m from \e[34m$localAddressString\e[m...");
		break;

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

	case TcpConnectionLogRecordCode.ConnectCompleted:
		target.m_lineAttr.m_flags = log.LineAttrFlags.Override;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Connect;
		target.m_lineAttr.m_backColor = log.StdLogColor.Connect;
		target.addHyperText (TcpConnectionPartCode.ConnectCompleted, "ok");
		break;

	case TcpConnectionLogRecordCode.ConnectCancelled:
		target.addHyperText (TcpConnectionPartCode.ConnectCompleted, "cancelled");
		break;

	case TcpConnectionLogRecordCode.ConnectError:
		target.m_lineAttr.m_flags = log.LineAttrFlags.Override;
		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Error;
		target.m_lineAttr.m_backColor = log.StdLogColor.Error;

		std.Error const* error = (std.Error const*) p;
		target.addHyperText (TcpConnectionPartCode.ConnectCompleted, $"error: $(error.m_description)");
		break;

	case TcpConnectionLogRecordCode.Disconnected:
		TcpDisconnectLogRecordParams const* params = (TcpDisconnectLogRecordParams const*) p;
		char const* addressString = params->m_address.getString ();
		char const* closeKind = (params.m_flags & TcpDisconnectLogRecordFlags.Reset) ? "reset" : "closed";
		char const* initiator = (params.m_flags & TcpDisconnectLogRecordFlags.Remote) ? "remote" : "local";

		target.m_lineAttr.m_iconIdx = log.StdLogIcon.Disconnect;
		target.m_lineAttr.m_backColor = log.StdLogColor.Disconnect;	
		target.addHyperText ($"Disconnected from \e[34m$addressString\e[m ($closeKind by $initiator node)");
		break;

	default:
		return false;
	}

	return true;
}

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