package com.dianping.cat.report.page.metric;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.dianping.cat.consumer.metric.model.entity.Metric;
import com.dianping.cat.consumer.metric.model.entity.MetricReport;
import com.dianping.cat.consumer.metric.model.entity.Point;
import com.dianping.cat.consumer.metric.model.transform.BaseVisitor;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.page.metric.MetricConfig.MetricFlag;
import com.google.gson.Gson;

public class MetricDisplay extends BaseVisitor {

	private Map<String, GraphItem> m_metrics = new LinkedHashMap<String, GraphItem>();

	private String m_key;

	private String m_channel;

	private Date m_start;

	private MetricConfig m_config;

	private static final String COUNT = ":count";

	public MetricDisplay(MetricConfig metricConfig, String channel, Date start) {
		m_config = metricConfig;
		m_start = start;
		m_channel = channel;

		for (MetricFlag flag : m_config.getFlags()) {
			String title = flag.getTitle();
			if (flag.isShowSum()) {
				String key = flag.getKey() + ":sum";
				m_metrics.put(key, new GraphItem(m_start, title, flag.getKey()));
			}
			if (flag.isShowCount()) {
				String key = flag.getKey() + COUNT;
				m_metrics.put(key, new GraphItem(m_start, title, flag.getKey()));
			}
			if (flag.isShowAvg()) {
				String key = flag.getKey() + ":avg";
				m_metrics.put(key, new GraphItem(m_start, title, flag.getKey()));
			}
		}
	}

	public List<GraphItem> getGroups() {
		return new ArrayList<GraphItem>(m_metrics.values());
	}

	@Override
	public void visitMetric(Metric metric) {
		m_key = metric.getId();

		if (StringUtils.isEmpty(m_channel)) {
			buildGraphItem(metric.getPoints().values());
		} else {
			Map<String, Metric> metrics = metric.getMetrics();
			Metric m = metrics.get("channel=" + m_channel);
			
			if (m != null) {
				buildGraphItem(m.getPoints().values());
			}
		}
	}

	private void buildGraphItem(Collection<Point> points) {
		for (Point point : points) {

			int min = point.getId();
			long count = point.getCount();
			double sum = point.getSum();
			double avg = point.getAvg();

			GraphItem graphItem = m_metrics.get(m_key + ":sum");
			if (graphItem != null) {
				graphItem.setValue(min, sum);
			}
			graphItem = m_metrics.get(m_key + ":count");
			if (graphItem != null) {
				graphItem.setValue(min, count);
			}
			graphItem = m_metrics.get(m_key + ":avg");
			if (graphItem != null) {
				graphItem.setValue(min, avg);
			}
		}
	}

	@Override
	public void visitMetricReport(MetricReport metricReport) {
		super.visitMetricReport(metricReport);
	}

	public static class GraphItem {
		private transient SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");

		private int size = 60;

		private long step = TimeUtil.ONE_MINUTE;

		private String start;

		private String title;

		private String key;

		private double[] values = new double[60];

		public GraphItem(Date start, String title, String key) {
			this.start = sdf.format(start);
			this.title = title;
			this.key = key;
		}

		public GraphItem addSubTitle(String title) {
			return this;
		}

		public String getJsonString() {
			Gson gson = new Gson();
			return gson.toJson(this);
		}

		public int getSize() {
			return this.size;
		}

		public String getStart() {
			return this.start;
		}

		public long getStep() {
			return step;
		}

		public String getTitle() {
			return this.title;
		}

		public GraphItem setSize(int size) {
			this.size = size;
			return this;
		}

		public GraphItem setStart(Date start) {
			this.start = sdf.format(start);
			return this;
		}

		public void setStep(long step) {
			this.step = step;
		}

		public GraphItem setTitle(String titles) {
			this.title = titles;
			return this;
		}

		public GraphItem setValue(int minute, double value) {
			values[minute] = value;
			return this;
		}

		public String getKey() {
			return key;
		}

		public double[] getValues() {
			return values;
		}

		public void setValues(double[] values) {
			this.values = values;
		}
	}

}

@@ -921,56 +921,8 @@
 g;%0A%0A
-%09private static final String COUNT = %22:count%22;%0A%0A
 %09pub
@@ -1358,13 +1358,16 @@
 ) + 
-COUNT
+%22:count%22
 ;%0A%09%09
@@ -1971,19 +1971,16 @@
 annel);%0A
-%09%09%09
 %0A%09%09%09if (

modify the metric title