package com.dianping.cat.report.task.exceptionAlert;

import com.dianping.cat.consumer.top.model.entity.Domain;
import com.dianping.cat.consumer.top.model.entity.Error;
import com.dianping.cat.consumer.top.model.entity.Segment;
import com.dianping.cat.consumer.top.model.entity.TopReport;
import com.dianping.cat.consumer.top.model.transform.BaseVisitor;
import com.dianping.cat.home.alertReport.entity.AlertReport;
import com.dianping.cat.home.dependency.exception.entity.ExceptionLimit;
import com.dianping.cat.system.config.ExceptionThresholdConfigManager;

public class TopReportVisitor extends BaseVisitor {

	private ExceptionThresholdConfigManager m_configManager;

	private AlertReport m_report;

	private String m_currentDomain;
	
	public TopReportVisitor(ExceptionThresholdConfigManager configManager) {
		m_configManager = configManager;
	}

	public TopReportVisitor setReport(AlertReport report) {
		m_report = report;
		return this;
	}

	@Override
	public void visitDomain(Domain domain) {
		m_currentDomain = domain.getName();
		super.visitDomain(domain);
	}

	@Override
	public void visitError(Error error) {
		int warnLimit = 0;
		int errorLimit = 0;

		ExceptionLimit exceptionLimit = m_configManager.queryDomainExceptionLimit(m_currentDomain, error.getId());

		if (exceptionLimit == null) {
			exceptionLimit = m_configManager.queryDomainTotalLimit(m_currentDomain);
		}
		if (exceptionLimit != null) {
			warnLimit = exceptionLimit.getWarning();
			errorLimit = exceptionLimit.getError();
		}
		int count = error.getCount();
		
		if (errorLimit > 0 & warnLimit > 0 & count < Math.min(warnLimit, errorLimit)) {
			return;
		}
		
		com.dianping.cat.home.alertReport.entity.Domain domain = m_report.findOrCreateDomain(m_currentDomain);
		domain.setName(m_currentDomain);

		com.dianping.cat.home.alertReport.entity.Exception exception = domain.findOrCreateException(error.getId());

		if (errorLimit > 0 && count >= errorLimit) {
			exception.incErrorNumber();
			domain.incErrorNumber();
		} else if (warnLimit > 0 && count >= warnLimit) {
			exception.incWarnNumber();
			domain.incWarnNumber();
		}
	}

	@Override
	public void visitSegment(Segment segment) {
		long totalSegmentException =  segment.getError();
		ExceptionLimit exceptionLimit = m_configManager.queryDomainTotalLimit(m_currentDomain);
		int warnLimit = -1;
		int errorLimit = -1;
		if(exceptionLimit != null) {
			warnLimit = exceptionLimit.getWarning();
			errorLimit = exceptionLimit.getError();
		}
		com.dianping.cat.home.alertReport.entity.Domain domain = m_report.findOrCreateDomain(m_currentDomain);
		if (errorLimit > 0 && totalSegmentException >= errorLimit) {
			domain.incErrorNumber();
		} else if (warnLimit > 0 && totalSegmentException >= warnLimit) {
			domain.incWarnNumber();
		}
		super.visitSegment(segment);
	}

	@Override
	public void visitTopReport(TopReport topReport) {
		super.visitTopReport(topReport);
	}
}

@@ -733,16 +733,94 @@
 main;%0A%09%0A
+%09private static final String TOTAL_EXCEPTION_ALERT = %22TotalExceptionAlert%22;%0A%09%0A
 %09public 
@@ -2664,16 +2664,137 @@
 omain);%0A
+%09%09com.dianping.cat.home.alertReport.entity.Exception exception = domain.findOrCreateException(TOTAL_EXCEPTION_ALERT);%0A%09%09%0A
 %09%09if (er
@@ -2868,32 +2868,63 @@
 cErrorNumber();%0A
+%09%09%09exception.incErrorNumber();%0A
 %09%09%7D else if (war
@@ -2998,24 +2998,54 @@
 rnNumber();%0A
+%09%09%09exception.incWarnNumber();%0A
 %09%09%7D%0A%09%09super.

add total exception alert number