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

import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.unidal.lookup.annotation.Inject;

import com.dianping.cat.Constants;
import com.dianping.cat.configuration.NetworkInterfaceManager;
import com.dianping.cat.configuration.ServerConfigManager;
import com.dianping.cat.consumer.heartbeat.HeartbeatAnalyzer;
import com.dianping.cat.consumer.heartbeat.model.entity.HeartbeatReport;
import com.dianping.cat.consumer.heartbeat.model.entity.Machine;
import com.dianping.cat.consumer.heartbeat.model.transform.BaseVisitor;
import com.dianping.cat.core.dal.HourlyReport;
import com.dianping.cat.helper.TimeHelper;
import com.dianping.cat.home.jar.entity.Domain;
import com.dianping.cat.home.jar.entity.Jar;
import com.dianping.cat.home.jar.entity.JarReport;
import com.dianping.cat.home.jar.transform.DefaultNativeBuilder;
import com.dianping.cat.report.service.ReportServiceManager;
import com.dianping.cat.report.task.spi.TaskBuilder;

public class JarReportBuilder implements TaskBuilder {

	public static final String ID = Constants.REPORT_JAR;

	@Inject
	private ReportServiceManager m_reportService;

	@Inject
	private ServerConfigManager m_configManager;

	public static List<String> s_jars = Arrays.asList("cat-client", "cat-core", "dpsf-net", "lion-client",
	      "avatar-cache", "zebra-ds-monitor-client", "zebra-api", "swallow-client", "swallow-consumerclient",
	      "swallow-producerclient", "platform-sdk");

	@Override
	public boolean buildDailyTask(String name, String domain, Date period) {
		throw new RuntimeException(ID + " don't support daily update");
	}

	@Override
	public boolean buildHourlyTask(String name, String domain, Date period) {
		Date end = new Date(period.getTime() + TimeHelper.ONE_HOUR);
		Set<String> domains = m_reportService.queryAllDomainNames(period, end, HeartbeatAnalyzer.ID);
		JarReport jarReport = new JarReport();
		HearbeartReportVisitor visitor = new HearbeartReportVisitor(jarReport);

		for (String domainName : domains) {
			if (m_configManager.validateDomain(domainName)) {
				HeartbeatReport heartbeatReport = m_reportService.queryHeartbeatReport(domainName, period, end);

				visitor.visitHeartbeatReport(heartbeatReport);
			}
		}
		jarReport.setStartTime(period);
		jarReport.setEndTime(end);

		HourlyReport report = new HourlyReport();

		report.setContent("");
		report.setCreationDate(new Date());
		report.setDomain(domain);
		report.setIp(NetworkInterfaceManager.INSTANCE.getLocalHostAddress());
		report.setName(name);
		report.setPeriod(period);
		report.setType(1);
		byte[] binaryContent = DefaultNativeBuilder.build(jarReport);
		return m_reportService.insertHourlyReport(report, binaryContent);
	}

	public class HearbeartReportVisitor extends BaseVisitor {

		private String m_currentDomain;

		private JarReport m_jarReport;

		public HearbeartReportVisitor(JarReport jarReport) {
			m_jarReport = jarReport;
		}

		@Override
		public void visitHeartbeatReport(HeartbeatReport heartbeatReport) {
			m_currentDomain = heartbeatReport.getDomain();
			super.visitHeartbeatReport(heartbeatReport);
		}

		@Override
		public void visitMachine(Machine machine) {
			String ip = machine.getIp();
			String classpath = machine.getClasspath();

			if (classpath != null) {
				String[] jars = classpath.split(",");
				Map<String, String> result = new LinkedHashMap<String, String>();

				for (String base : s_jars) {
					result.put(base, "-");
				}
				for (String jar : jars) {
					int lastIndex = jar.lastIndexOf("-");

					if (lastIndex > -1) {
						String jarName = jar.substring(0, lastIndex);
						String version = result.get(jarName);

						if (version != null) {
							String newVersion = jar.substring(lastIndex + 1, jar.lastIndexOf("."));

							result.put(jarName, newVersion);
						}
					}
				}
				Domain domainInfo = m_jarReport.findOrCreateDomain(m_currentDomain);
				com.dianping.cat.home.jar.entity.Machine machineinfo = domainInfo.findOrCreateMachine(ip);

				for (Entry<String, String> entry : result.entrySet()) {
					Jar jar = new Jar();

					jar.setId(entry.getKey()).setVersion(entry.getValue());
					machineinfo.addJar(jar);
				}
			}
		}
	}

	@Override
	public boolean buildMonthlyTask(String name, String domain, Date period) {
		throw new RuntimeException(ID + " don't support monthly update");
	}

	@Override
	public boolean buildWeeklyTask(String name, String domain, Date period) {
		throw new RuntimeException(ID + " don't support weekly update");
	}

}

@@ -2030,28 +2030,28 @@
 rt();%0A%09%09Hear
+t
 bea
-r
 tReportVisit
@@ -2067,28 +2067,28 @@
 r = new Hear
+t
 bea
-r
 tReportVisit
@@ -2851,28 +2851,28 @@
 c class Hear
+t
 bea
-r
 tReportVisit
@@ -2983,12 +2983,12 @@
 Hear
+t
 bea
-r
 tRep

modify the builder