package com.zhiwei.manage.handle;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

import com.zhiwei.manage.bean.Channel;
import com.zhiwei.manage.bean.CrawTemplate;
import com.zhiwei.manage.bean.Data;
import com.zhiwei.manage.bean.FieldIntegerity;
import com.zhiwei.manage.bean.Message;
import com.zhiwei.manage.bean.NewsDelayed;
import com.zhiwei.manage.bean.PingUrl;
import com.zhiwei.manage.bean.Template;
import com.zhiwei.manage.orm.BeanFactory;
import com.zhiwei.manage.service.CrawTemplateServiceImpl;
import com.zhiwei.manage.service.DataServiceImpl;
import com.zhiwei.manage.service.MessageServiceImpl;
import com.zhiwei.manage.service.ServerServiceImpl;
import com.zhiwei.manage.util.TimeUtil;
import com.zhiwei.manage.util.Tools;

@Component
public class MainThread extends Thread {

	private static final Log log = LogFactory.getLog(MainThread.class);
	public static Map<String, Template> mainMap = new ConcurrentHashMap<String, Template>();
	public static Map<String, Template> allTmp = new ConcurrentHashMap<String, Template>();
	private static Lock mainLock = new ReentrantLock();

	public MainThread() {
		this.start();
	}

	/**
	 * 加入执行map
	 * 
	 * @param template
	 */
	public static boolean pushMap(String templateId) {
		Template template = allTmp.get(templateId);
		if (mainMap.get(templateId) != null) {
			return false;
		} else {
			mainMap.put(template.getTemplateId(), template);
			System.out.println("加入模板" + template);
			if (template.isNeedDelayed()) {
				NewsDelayed nd = new NewsDelayed();
				nd.setCollection(template.getCollection());
				nd.setNewsDelayed(template.getNewsDelayed());
				nd.setDelayedInterval(template.getDelayedInterval());
				nd.setdBName(template.getdBName());
				nd.setHost(template.getHost());
				nd.setPort(template.getPort());
				nd.setStartNow(false);
				nd.setPt(template.getPt());
				nd.setSavetime(template.getSavetime());
				nd.setTime(template.getTime());
				nd.setSpyderInfoId(template.getSpyderInfoId());
				nd.setTempName(template.getTempName());
				nd.setNextRun(new Date());
				nd.setTestCount(template.getTestCount());
				nd.setTemplateId(templateId);
				DelayedThread.runMap.put(template.getTemplateId(), nd);
			}
			if (template.isNeedPing()) {
				log.info("ping测试添加");
				PingUrl ping = new PingUrl();
				ping.setNextRun(new Date());
				ping.setPingInterval(template.getPingInterval());
				ping.setPingUrlOne(template.getPingUrlOne());
				ping.setPingUrlTwo(template.getPingUrlTwo());
				ping.setPt(template.getPt());
				ping.setTemplateId(templateId);
				ping.setTempName(template.getTempName());
				ping.setStartNow(false);
				PingThread.runMap.put(templateId, ping);
			}
			if (template.isNeedField()) {
				FieldIntegerity fb = new FieldIntegerity();
				fb.setTestCount(template.getTestCount());
				fb.setCollection(template.getCollection());
				fb.setTemplateId(templateId);
				fb.setdBName(template.getdBName());
				fb.setHost(template.getHost());
				fb.setPort(template.getPort());
				fb.setNextRun(new Date());
				fb.setStartNow(false);
				fb.setPt(template.getPt());
				fb.setSpyderInfoId(template.getSpyderInfoId());
				fb.setTempName(template.getTempName());
				fb.setField(template.getField());
				fb.setFieldIntegrityRate(template.getFieldIntegrityRate());
				fb.setFieldInterval(template.getFieldInterval());
				FieldThread.runMap.put(template.getTemplateId(), fb);
			}
			return true;
		}
	}

	/**
	 * 停止该执行
	 * 
	 * @param template
	 */
	public static boolean removeMap(String templateId) {
		try {
			if (DelayedThread.runMap.get(templateId) != null)
				DelayedThread.runMap.remove(templateId);
			if (PingThread.runMap.get(templateId) != null)
				PingThread.runMap.remove(templateId);
			if (FieldThread.runMap.get(templateId) != null)
				FieldThread.runMap.remove(templateId);
			if (mainMap.get(templateId) != null) {
				mainMap.remove(templateId);
			}
			if (allTmp.get(templateId) != null)
				allTmp.remove(templateId);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static boolean delete(String templateId) {
		allTmp.remove(templateId);
		return true;
	}

	@Override
	public void run() {
		log.info("=======日常入库启动======");
		CrawTemplateServiceImpl crawService = BeanFactory.getBean(CrawTemplateServiceImpl.class);
		DataServiceImpl dataService = BeanFactory.getBean(DataServiceImpl.class);
		ServerServiceImpl serverService = BeanFactory.getBean(ServerServiceImpl.class);
		MessageServiceImpl msgService = BeanFactory.getBean(MessageServiceImpl.class);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH");
		while (true) {
			String today = sdf.format(new Date());
			Date d = new Date();
			Calendar start = Calendar.getInstance();
			Calendar end = Calendar.getInstance();
			try {
				d = sdf.parse(today);
				start.setTime(sdf2.parse(sdf2.format(start.getTime())));
				if (start.get(Calendar.HOUR_OF_DAY) > 1) {
					start.add(Calendar.HOUR_OF_DAY, -1);
				} else {
					start.setTime(sdf.parse(today));
				}
				end.setTime(sdf2.parse(sdf2.format(end.getTime())));
			} catch (ParseException e2) {
				e2.printStackTrace();
			}
			try {
				mainLock.lock();
				int count = 0;
				List<Channel> channel = serverService.findDisChannel();
				for (Channel chan : channel) {
					try {
						count = (int) dataService.finCountByDayData(start.getTime(), end.getTime(), chan.getPt());
						Data data = new Data();
						data.setCount(count);
						data.setPt(chan.getPt());
						data.setTime(d);
						dataService.insert(data);
						log.info(TimeUtil.yearToDay(start.getTime()) + "|" + chan.getPt() + "|入库");
					} catch (Exception e) {
						log.error(chan.getPt() + "入库出错，错误信息{}", e);
					}
				}
				Set<String> keys = allTmp.keySet();
				for (Iterator<String> it = keys.iterator(); it.hasNext();) {
					String key = it.next();
					Template tmp = allTmp.get(key);
					if (tmp.getSpyderInfoId() != null) {
						int cwCount = 0;
						String pt = crawService.findPt(tmp.getSpyderInfoId());
						cwCount = (int) dataService.finCountByDayData(start.getTime(), end.getTime(), tmp);
						try {
							Data data = new Data();
							data.setCount(cwCount);
							data.setTime(d);
							data.setTempName(tmp.getTempName());
							dataService.insert(data);
							log.info(TimeUtil.yearToDay(start.getTime()) + "|" + tmp.getTempName() + "|入库");
						} catch (Exception e) {
							log.error(tmp.getTempName() + "入库出错，错误信息{}", e);
						}
						if (cwCount < tmp.getNewsNumber()) {
							Message m = new Message();
							m.setHandle(false);
							m.setCreateDate(d);
							m.setTemplateLv(tmp.getTemplateLv());
							m.setTempName(tmp.getTempName());
							m.setErrorType("count");
							m.setPt(pt);
							m.setErrorMsg("数据量检测：" + tmp.getTempName() + "的数据为小于" + tmp.getNewsNumber());
							msgService.insert(m);
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				mainLock.unlock();
			}
			Tools.sleep(1000 * 60 * 60);
		}
	}

}
