package com.persagy.functions.weather.thread;

import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import com.persagy.core.mvc.service.CoreService;
import com.persagy.ems.pojo.wz.MinuteRecordData;
import com.persagy.framework.util.ConfigUtil;
import com.persagy.framework.util.DateUtils;
import com.persagy.framework.util.WServiceUtil;
import com.persagy.functions.weather.constant.Const;

/**
 * 龙湖定制5min天气数据记录
 */
public class Min5LongHuThread implements Runnable {
	private static final Logger log = Logger.getLogger(Min5LongHuThread.class);
	
	private static Set<String> updateCitySet = new HashSet<>();
	
	private CoreService service;
	
	private static final String tname = "LongHu5min";
	
	public Min5LongHuThread(CoreService service) {
		this.service = service;
	}
	
	@Override
	public void run() {

		log.info(tname +" 线程启动...");
		Date dateNow = new Date();
		Date dateTemp = dateNow;
		try {
			dateTemp = DateUtils.getShortDate(dateNow, 2);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		while(dateTemp.before(dateNow)) {
			dateTemp = DateUtils.getMinuteOff(dateTemp, 5);
		}
		dateTemp = DateUtils.getMinuteOff(dateTemp, -20);
		
		while(true) {
			updateMap();
			
			if(!updateCitySet.isEmpty()) {
				
				Long dateHourFirst5min = dateTemp.getTime() + Const.AboutTime.min5Minlliseconds;
				
				if(dateHourFirst5min > new Date().getTime()) {
					Long sleepMinlliseconds = dateHourFirst5min - new Date().getTime();
					log.info(tname + " thread wait "+ (sleepMinlliseconds / (1.0 * Const.AboutTime.minMinlliseconds)) + "min");
					try {
						Thread.sleep(sleepMinlliseconds);
					}catch (Exception e) {
						e.printStackTrace();
					}
				}else {
					dateTemp = DateUtils.getMinuteOff(dateTemp, 5);
					
					String executeResult = min5RecordHandle(dateTemp);
					
					log.info(tname + " execute result:"+executeResult);
				}
			}else {
				log.info(tname + " no city need to record 5min data, sleep 1 min");
				try {
					Thread.sleep(Const.AboutTime.minMinlliseconds);
				}catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private String min5RecordHandle(Date dateTemp) {
		int saveTotal = updateCitySet.size();
		int saveFailedNum = 0;
		Set<String> saveFailedSet = new HashSet<>();
		int saveSuccessNum = 0;
		
		
		for(String cityId : updateCitySet) {
			try {
				Map<String, Object> weatherResult = WServiceUtil.getNowWeather(cityId);
				String temperature = weatherResult.get("temperature")+"";
				if("null".equals(temperature)) {
					throw new Exception("can not get temperature data!");
				}else {
					MinuteRecordData mrd = new MinuteRecordData();
					mrd.setBuildingForContainer(cityId);
					mrd.setCityId(cityId);
					mrd.setType(1);
					mrd.setMinuteTime(dateTemp);
					mrd.setData(Double.parseDouble(temperature));
					
					service.save(mrd);
					saveSuccessNum ++;
				}
			} catch (Exception e) {
				saveFailedNum ++;
				saveFailedSet.add(cityId);
				log.error(e.getMessage());
			}
		}
		
		String resultMsg = tname + " total-success-failed=" + saveTotal + "-" + saveSuccessNum + "-" + saveFailedNum;
		if(!saveFailedSet.isEmpty()) {
			resultMsg += ", saveFailed=" + saveFailedSet;
		}
		
		return resultMsg;
	}
	
	private void updateMap() {
		Set<String> hourCitySet = new HashSet<>(ConfigUtil.longHu5MinCitiesGet().values());
		
		if(!hourCitySet.isEmpty()) {
			int addNum = 0;
			for(String cityId : hourCitySet) {
				if(!updateCitySet.contains(cityId)) {
					addNum ++;
				}
				updateCitySet.add(cityId);
			}
			if(addNum > 0) {
				log.info("longhu 5min city add " + addNum);
			}
		}
	}
}
