package com.persagy.functions.weather.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.persagy.core.enumeration.SpecialOperator;
import com.persagy.core.mvc.service.CoreService;
import com.persagy.ems.pojo.wz.BusinessApiStatic;
import com.persagy.ems.pojo.wz.DependApiStatic;
import com.persagy.framework.util.DateUtils;
import com.persagy.functions.weather.constant.Const;
import com.persagy.functions.weather.constant.ConstBusinessStatic;
import com.persagy.functions.weather.service.DependApiStaticService;

@Service("dependApiStaticService")
public class DependApiStaticServiceImpl implements DependApiStaticService {
	private static final Logger log = Logger.getLogger(DependApiStaticServiceImpl.class);
	@Resource(name="coreService")
	private CoreService coreService;
	
	@Override
	public void doStatistics(String type) throws Exception{
		Date updateTime = new Date();
		
		dependApiStatistic(type, updateTime);
		if("Business".equals(type)) {
			businessApiStatistic(updateTime);
			clearOldData(updateTime);
		}
	}

	private void clearOldData(Date updateTime) throws Exception {
		int hourIndex = DateUtils.getHour(updateTime);
		if(hourIndex < 1) {
			Date day7before = DateUtils.getDayOff(updateTime, -7);
			
			BusinessApiStatic removeB = new BusinessApiStatic();
			removeB.setSpecialOperation("hourTime", SpecialOperator.$lt, day7before);
			coreService.remove(removeB);
			
			DependApiStatic removeD = new DependApiStatic();
			removeD.setSpecialOperation("dayTime", SpecialOperator.$lt, day7before);
			coreService.remove(removeD);
			
			log.info("清除7天前的接口访问统计数据...");
		}
	}

	private void businessApiStatistic(Date updateTime) throws Exception {
		Date hourTime = DateUtils.getShortDate(updateTime, 2);
		BusinessApiStatic queryObj = new BusinessApiStatic();
		queryObj.setHourTime(hourTime);
		List<BusinessApiStatic> list = coreService.query(queryObj);
		
		Map<String, BusinessApiStatic> recordMap = new HashMap<>();
		if(null != list && !list.isEmpty()) {
			for(BusinessApiStatic obj : list) {
				recordMap.put(obj.getIp()+"_"+obj.getApi(), obj);
			}
		}
		
		Map<String, Integer> nowStatis = ConstBusinessStatic.getAndFlush();
		if(null != nowStatis && !nowStatis.isEmpty()) {
			List<BusinessApiStatic> saveList = new ArrayList<>();
			
			Set<String> ipSet = new HashSet<>();
			Set<String> apiSet = new HashSet<>();
			
			String ip = null, api = null;
			for(String name : nowStatis.keySet()) {
				ip = name.substring(0, name.indexOf("_"));
				api = name.substring(name.indexOf("_")+1);
				ipSet.add(ip); 
				apiSet.add(api);
				
				BusinessApiStatic newRecord = recordMap.get(name);
				if(newRecord == null) {
					newRecord = new BusinessApiStatic();
					saveList.add(newRecord);
					
					newRecord.setUpdateTime(updateTime);
					newRecord.setHourTime(hourTime);
					newRecord.setIp(ip);
					newRecord.setApi(api);
					newRecord.setNum(nowStatis.get(name));
					
				}else {
					newRecord.setUpdateTime(updateTime);
					newRecord.setNum(nowStatis.get(name) + newRecord.getNum());
					
					BusinessApiStatic paramObj = new BusinessApiStatic();
					paramObj.setIp(ip);
					paramObj.setApi(api);
					paramObj.setHourTime(hourTime);
					coreService.update(paramObj, newRecord);
				}
			}
			
			if(!saveList.isEmpty()) {
				coreService.save(saveList);
			}
			
			log.info("BusinessApiStatic ipNum=" + ipSet.size() + ", apiNum=" + apiSet.size());
		}
	}

	private void dependApiStatistic(String type, Date updateTime) throws Exception {
		Date dayTime = DateUtils.getShortDate(updateTime, 3);
		DependApiStatic queryObj = new DependApiStatic();
		queryObj.setDayTime(dayTime);
		queryObj.setType(type);
		List<DependApiStatic> list = coreService.query(queryObj);
		
		Map<String, DependApiStatic> recordMap = new HashMap<>();
		if(null != list && !list.isEmpty()) {
			for(DependApiStatic obj : list) {
				recordMap.put(obj.getName(), obj);
			}
		}
		
		Map<String, Integer> nowStatis = Const.popAll();
		if(null != nowStatis && !nowStatis.isEmpty()) {
			for(String name : nowStatis.keySet()) {
				DependApiStatic newRecord = recordMap.get(name);
				if(newRecord == null) {
					newRecord = new DependApiStatic();
					newRecord.setType(type);
					newRecord.setName(name);
					newRecord.setDayTime(dayTime);
					newRecord.setUpdateTime(updateTime);
					newRecord.setNum(nowStatis.get(name));
					coreService.save(newRecord);
				}else {
					newRecord.setUpdateTime(updateTime);
					newRecord.setType(type);
					newRecord.setNum(nowStatis.get(name) + newRecord.getNum());
					
					DependApiStatic updateObj = new DependApiStatic();
					updateObj.setName(name);
					updateObj.setType(type);
					updateObj.setDayTime(dayTime);
					coreService.update(updateObj, newRecord);
				}
			}
			
			log.info("DependApiStatic data=" + nowStatis);
		}
	}

}
