<commit_before>package com.dianping.cat.message.spi.codec;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.jboss.netty.buffer.ChannelBuffer;

import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.message.internal.MockMessageBuilder;
import com.dianping.cat.message.spi.MessageCodec;
import com.dianping.cat.message.spi.MessageTree;
import com.site.lookup.annotation.Inject;

/**
 * Local use only, do not use it over network since it only supports one-way encoding
 */
public class WaterfallMessageCodec implements MessageCodec, Initializable {
	public static final String ID = "waterfall";

	private static final String VERSION = "WF1"; // Waterfall version 1

	@Inject
	private BufferWriter m_writer;

	private BufferHelper m_bufferHelper;

	private boolean m_mockMode = false;

	protected int countTransactions(Transaction t) {
		int count = 1;

		for (Message child : t.getChildren()) {
			if (child instanceof Transaction) {
				count += countTransactions((Transaction) child);
			}
		}

		return count;
	}

	@Override
	public MessageTree decode(ChannelBuffer buf) {
		throw new UnsupportedOperationException("HtmlMessageCodec only supports one-way encoding!");
	}

	@Override
	public void decode(ChannelBuffer buf, MessageTree tree) {
		throw new UnsupportedOperationException("HtmlMessageCodec only supports one-way encoding!");
	}

	@Override
	public void encode(MessageTree tree, ChannelBuffer buf) {
		Message message = tree.getMessage();

		if (m_mockMode) {
			message = mockTransaction();
			tree.setMessage(message);
		}

		if (message instanceof Transaction) {
			int count = 0;
			int index = buf.writerIndex();
			BufferHelper helper = m_bufferHelper;
			Transaction t = (Transaction) message;
			Locator locator = new Locator();
			Ruler ruler = new Ruler((int) t.getDurationInMicros());

			ruler.setWidth(1400);
			ruler.setHeight(18 * countTransactions(t) + 10);
			ruler.setOffsetX(200);
			ruler.setOffsetY(10);

			buf.writeInt(0); // place-holder

			count += helper.table1(buf);
			count += helper.crlf(buf);
			count += encodeHeader(tree, buf, ruler);

			count += encodeRuler(buf, locator, ruler);
			count += encodeTransaction(tree, t, buf, locator, ruler);

			count += encodeFooter(tree, buf);
			count += helper.table2(buf);
			buf.setInt(index, count);
		}
	}

	protected int encodeFooter(MessageTree tree, ChannelBuffer buf) {
		BufferHelper helper = m_bufferHelper;
		XmlBuilder b = new XmlBuilder();
		StringBuilder sb = b.getResult();

		b.tag2("g");
		b.tag2("svg");
		sb.append("</td></tr>");

		int count = helper.write(buf, sb.toString());
		return count;
	}

	protected int encodeHeader(MessageTree tree, ChannelBuffer buf, Ruler ruler) {
		BufferHelper helper = m_bufferHelper;
		XmlBuilder b = new XmlBuilder();
		StringBuilder sb = b.getResult();

		sb.append("<tr class=\"header\"><td>");
		sb.append(VERSION).append(" ").append(tree.getDomain()).append(" ");
		sb.append(tree.getHostName()).append(" ").append(tree.getIpAddress()).append(" ");
		sb.append(tree.getThreadGroupName()).append(" ").append(tree.getThreadId()).append(" ");
		sb.append(tree.getThreadName()).append(" ").append(tree.getMessageId()).append(" ");
		sb.append(tree.getParentMessageId()).append(" ").append(tree.getRootMessageId()).append(" ");
		sb.append(tree.getSessionToken()).append(" ");
		sb.append("</td></tr>");
		sb.append("<tr><td>");

		int height = ruler.getHeight();
		int width = ruler.getWidth();

		b.add("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n");
		b.tag1("svg", "x", 0, "y", 0, "width", width, "height", height, "viewBox", "0,0," + width + "," + height, "xmlns",
		      "http://www.w3.org/2000/svg");
		b.tag1("g", "font-size", "12", "stroke", "gray");

		int count = helper.write(buf, sb.toString());
		return count;
	}

	protected int encodeLine(MessageTree tree, Transaction t, ChannelBuffer buf, Locator locator, Ruler ruler) {
		BufferHelper helper = m_bufferHelper;
		XmlBuilder b = new XmlBuilder();
		StringBuilder sb = b.getResult();
		int width = 6;
		int height = 18;
		int x = 0;
		int y = locator.getLine() * height + ruler.getOffsetY();

		b.branch(locator, x, y, width, height);

		x += locator.getLevel() * width;

		if (t.getStatus().equals("0")) {
			b.tagWithText("text", t.getType(), "x", x, "y", y - 5, "font-weight", "bold", "stroke-width", "0");
		} else {
			b.tagWithText("text", t.getType(), "x", x, "y", y - 5, "font-weight", "bold", "stroke-width", "0", "fill", "red");
		}

		long t0 = tree.getMessage().getTimestamp();
		long t1 = t.getTimestamp();
		long d = t.getDurationInMicros();

		int rx = ruler.calcX((t1 - t0) * 1000);
		int rw = ruler.calcX(d) - ruler.getOffsetX();

		b.tag("rect", "x", rx + 1, "y", y - 15, "width", rw, "height", height - 2, "fill", "#0066ff", "opacity", "0.5");
		b.tagWithText("text", String.format("%.2f %s", t.getDurationInMicros() / 1000.0, t.getName()), "x", rx + 5, "y", y - 3,
		      "font-size", "11", "stroke-width", "0");

		int count = helper.write(buf, sb.toString());
		return count;
	}

	protected int encodeRuler(ChannelBuffer buf, Locator locator, Ruler ruler) {
		BufferHelper helper = m_bufferHelper;
		XmlBuilder b = new XmlBuilder();
		StringBuilder sb = b.getResult();
		PathBuilder p = new PathBuilder();
		int height = 600;

		b.tag1("g", "id", "ruler", "font-size", "12", "text-anchor", "middle", "stroke", "black", "stroke-width", "1");

		int unitNum = ruler.getUnitNum();
		int unitStep = ruler.getUnitStep();
		int unit = (int) ruler.getUnit();
		int x = ruler.getOffsetX();
		int y = 10;<commit_msg>another bug fix<commit_after>package com.dianping.cat.message.spi.codec;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.jboss.netty.buffer.ChannelBuffer;

import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.message.internal.MockMessageBuilder;
import com.dianping.cat.message.spi.MessageCodec;
import com.dianping.cat.message.spi.MessageTree;
import com.site.lookup.annotation.Inject;

/**
 * Local use only, do not use it over network since it only supports one-way encoding
 */
public class WaterfallMessageCodec implements MessageCodec, Initializable {
	public static final String ID = "waterfall";

	private static final String VERSION = "WF1"; // Waterfall version 1

	@Inject
	private BufferWriter m_writer;

	private BufferHelper m_bufferHelper;

	private boolean m_mockMode = false;

	protected int countTransactions(Transaction t) {
		int count = 1;

		for (Message child : t.getChildren()) {
			if (child instanceof Transaction) {
				count += countTransactions((Transaction) child);
			}
		}

		return count;
	}

	@Override
	public MessageTree decode(ChannelBuffer buf) {
		throw new UnsupportedOperationException("HtmlMessageCodec only supports one-way encoding!");
	}

	@Override
	public void decode(ChannelBuffer buf, MessageTree tree) {
		throw new UnsupportedOperationException("HtmlMessageCodec only supports one-way encoding!");
	}

	@Override
	public void encode(MessageTree tree, ChannelBuffer buf) {
		Message message = tree.getMessage();

		if (m_mockMode) {
			message = mockTransaction();
			tree.setMessage(message);
		}

		if (message instanceof Transaction) {
			int count = 0;
			int index = buf.writerIndex();
			BufferHelper helper = m_bufferHelper;
			Transaction t = (Transaction) message;
			Locator locator = new Locator();
			Ruler ruler = new Ruler((int) t.getDurationInMicros());

			ruler.setWidth(1400);
			ruler.setHeight(18 * countTransactions(t) + 10);
			ruler.setOffsetX(200);
			ruler.setOffsetY(10);

			buf.writeInt(0); // place-holder

			count += helper.table1(buf);
			count += helper.crlf(buf);
			count += encodeHeader(tree, buf, ruler);

			count += encodeRuler(buf, locator, ruler);
			count += encodeTransaction(tree, t, buf, locator, ruler);

			count += encodeFooter(tree, buf);
			count += helper.table2(buf);
			buf.setInt(index, count);
		}
	}

	protected int encodeFooter(MessageTree tree, ChannelBuffer buf) {
		BufferHelper helper = m_bufferHelper;
		XmlBuilder b = new XmlBuilder();
		StringBuilder sb = b.getResult();

		b.tag2("g");
		b.tag2("svg");
		sb.append("</td></tr>");

		int count = helper.write(buf, sb.toString());
		return count;
	}

	protected int encodeHeader(MessageTree tree, ChannelBuffer buf, Ruler ruler) {
		BufferHelper helper = m_bufferHelper;
		XmlBuilder b = new XmlBuilder();
		StringBuilder sb = b.getResult();

		sb.append("<tr class=\"header\"><td>");
		sb.append(VERSION).append(" ").append(tree.getDomain()).append(" ");
		sb.append(tree.getHostName()).append(" ").append(tree.getIpAddress()).append(" ");
		sb.append(tree.getThreadGroupName()).append(" ").append(tree.getThreadId()).append(" ");
		sb.append(tree.getThreadName()).append(" ").append(tree.getMessageId()).append(" ");
		sb.append(tree.getParentMessageId()).append(" ").append(tree.getRootMessageId()).append(" ");
		sb.append(tree.getSessionToken()).append(" ");
		sb.append("</td></tr>");
		sb.append("<tr><td>");

		int height = ruler.getHeight();
		int width = ruler.getWidth();

		b.add("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n");
		b.tag1("svg", "x", 0, "y", 0, "width", width, "height", height, "viewBox", "0,0," + width + "," + height, "xmlns",
		      "http://www.w3.org/2000/svg");
		b.tag1("g", "font-size", "12", "stroke", "gray");

		int count = helper.write(buf, sb.toString());
		return count;
	}

	protected int encodeLine(MessageTree tree, Transaction t, ChannelBuffer buf, Locator locator, Ruler ruler) {
		BufferHelper helper = m_bufferHelper;
		XmlBuilder b = new XmlBuilder();
		StringBuilder sb = b.getResult();
		int width = 6;
		int height = 18;
		int x = 0;
		int y = locator.getLine() * height + ruler.getOffsetY();

		b.branch(locator, x, y, width, height);

		x += locator.getLevel() * width;

		if (t.getStatus().equals("0")) {
			b.tagWithText("text", t.getType(), "x", x, "y", y - 5, "font-weight", "bold", "stroke-width", "0");
		} else {
			b.tagWithText("text", t.getType(), "x", x, "y", y - 5, "font-weight", "bold", "stroke-width", "0", "fill", "red");
		}

		long t0 = tree.getMessage().getTimestamp();
		long t1 = t.getTimestamp();
		long d = t.getDurationInMicros();

		int rx = ruler.calcX((t1 - t0) * 1000);
		int rw = ruler.calcX(d) - ruler.getOffsetX();

		b.tag("rect", "x", rx + 1, "y", y - 15, "width", rw, "height", height - 2, "fill", "#0066ff", "opacity", "0.5");
		b.tagWithText("text", String.format("%.2f %s", t.getDurationInMicros() / 1000.0, t.getName()), "x", rx + 5, "y", y - 3,
		      "font-size", "11", "stroke-width", "0");

		int count = helper.write(buf, sb.toString());
		return count;
	}

	protected int encodeRuler(ChannelBuffer buf, Locator locator, Ruler ruler) {
		BufferHelper helper = m_bufferHelper;
		XmlBuilder b = new XmlBuilder();
		StringBuilder sb = b.getResult();
		PathBuilder p = new PathBuilder();
		int height = ruler.getHeight();

		b.tag1("g", "id", "ruler", "font-size", "12", "text-anchor", "middle", "stroke", "black", "stroke-width", "1");

		int unitNum = ruler.getUnitNum();
		int unitStep = ruler.getUnitStep();
		int unit = (int) ruler.getUnit();
		int x = ruler.getOffsetX();
		int y = 10;
{'fraction_non_alphanumeric': 0.1682741116751269, 'fraction_numerical': 0.014974619289340102, 'mean_word_length': 4.339205058717254, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7395548', 'n_tokens_mistral': 4357, 'n_tokens_neox': 3904, 'n_words': 943}