//..............................................................................
//
// Socket log representer
//

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

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

bool representSocketLog(
	log.Representation* representation,
	uint64_t recordCode,
	void const* p,
	size_t size,
	uint_t foldFlags
	)
{
	switch (recordCode)
	{
	case SocketLogRecordCode.Open:
		char const* addressString = ((io.SocketAddress const*) p).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Connect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Connect;
		representation.addHyperText($"Opened socket at \e[34m$addressString");
		break;

	case SocketLogRecordCode.OpenError:
		io.SocketAddress const* address = (io.SocketAddress const*) p;
		char const* addressString = address.getString();
		std.Error const* error = (std.Error const*) (address + 1);
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Error;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Error;
		representation.addHyperText($"Cannot open socket at \e[34m$addressString\e[m: $(error.m_description)");
		break;

	case SocketLogRecordCode.Close:
		char const* addressString = ((io.SocketAddress const*) p).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Disconnect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Disconnect;
		representation.addHyperText($"Socket at \e[34m$addressString\e[m closed");
		break;

	case SocketLogRecordCode.Resolving:
		char const* addressString = (char const*) p;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText(SocketLogPartCode.Connecting, $"Resolving \e[34m$addressString\e[m...");
		break;

	case SocketLogRecordCode.Connecting:
		char const* addressString = ((io.SocketAddress const*) p).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText(SocketLogPartCode.Connecting, $"Connecting to \e[34m$addressString\e[m...");
		break;

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

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

	case SocketLogRecordCode.ConnectCompleted:
		representation.m_lineAttr.m_flags = log.LineAttrFlags.Override;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Connect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Connect;
		representation.addHyperText(SocketLogPartCode.ConnectCompleted, "ok");
		break;

	case SocketLogRecordCode.ConnectCancelled:
		representation.addHyperText(SocketLogPartCode.ConnectCompleted, "cancelled");
		break;

	case SocketLogRecordCode.ConnectError:
		std.Error const* error = (std.Error const*) p;
		representation.m_lineAttr.m_flags = log.LineAttrFlags.Override;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Error;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Error;
		representation.addHyperText(SocketLogPartCode.ConnectCompleted, $"error: $(error.m_description)");
		break;

	case SocketLogRecordCode.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";

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

	case SocketLogRecordCode.Disconnected_old:
		char const* 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 from \e[34m$addressString\e[m");
		break;

	case SocketLogRecordCode.Listening:
		char const* addressString = ((io.SocketAddress const*) p).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Listen;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText($"Listening on \e[34m$addressString");
		break;

	case SocketLogRecordCode.ListenError:
		std.Error const* error = (std.Error const*) p;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Error;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Error;
		representation.addHyperText($"Cannot listen: $(error.m_description)");
		break;

	case SocketLogRecordCode.ListenStopped:
		char const* addressString = ((io.SocketAddress const*) p).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.StopListen;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText($"Stopped listening on \e[34m$addressString");
		break;

	case SocketLogRecordCode.ClientConnected:
		char const* addressString = ((io.SocketAddress const*) p).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Connect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Connect;
		representation.addHyperText($"Client connected from \e[34m$addressString");
		break;

	case SocketLogRecordCode.ClientDisconnected:
		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";

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

	case SocketLogRecordCode.ClientRejected:
		char const* addressString = ((io.SocketAddress const*) p).getString();
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Warning;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Warning;
		representation.addHyperText($"Client \e[34m$addressString\e[m is rejected ");
		break;

	default:
		return false;
	}

	return true;
}

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