package com.zhiwei.manage.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zhiwei.manage.bean.Data;
import com.zhiwei.manage.bean.ServerBean;
import com.zhiwei.manage.handle.DbDepot;
import com.zhiwei.manage.handle.MainThread;
import com.zhiwei.manage.service.CrawTemplateService;

/**
 * es工具类
 * 
 * @author admin
 */
@Component
public class ESUtil {
	private static final Logger log = LoggerFactory.getLogger(ESUtil.class);
	final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

	/**
	 * 获取匹配时终止时间
	 * 
	 * @param hour
	 * @return
	 */
	public static String getTimeMax(int hour) {
		SimpleDateFormat smf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = new Date();
		String time = "";
		time = smf.format(date) + "T0" + (hour - 8) + ":00:00.000Z";
		return time;
	}

	/**
	 * 数据查询。获取数量
	 * 
	 * @param start
	 * @param end
	 * @param pt
	 * @param type
	 * @param value
	 * @param spyderInfoId
	 * @return
	 */
	public int getDatas(Date start, Date end, String pt, String type, String value, String spyderInfoId,
			ServerBean ser) {
		Calendar startTime = Calendar.getInstance();
		startTime.setTime(start);
		startTime.add(Calendar.HOUR, -8);
		Calendar endTime = Calendar.getInstance();
		endTime.setTime(end);
		endTime.add(Calendar.HOUR, -8);
		Client esClient=null;
		try {
			if (DbDepot.esClients.get(pt) == null) {
				esClient = new ESClient(ser.getCollection(), ser.getDbHost(), ser.getDbPort()).getClient();
				DbDepot.esClients.put(pt, esClient);
			} else {
				esClient = (Client) DbDepot.esClients.get(pt);
			}
			// 搜索数据
			SearchRequestBuilder srb = esClient.prepareSearch(Config.getVal(MainThread.map.get(pt) + ".indexName"));
			BoolQueryBuilder bb = new BoolQueryBuilder();
			srb.setQuery(bb);
			addQuerys(pt, startTime, endTime, srb, bb);
			QueryBuilder matchQuery = QueryBuilders.matchPhraseQuery(type, value);
			bb.should(matchQuery);
			srb.setSize(1);
			SearchResponse response = srb.execute().actionGet();
			SearchHits searchHits = response.getHits();
			esClient.close();
			return (int) searchHits.getTotalHits();
		} catch (Exception e) {
			log.error("es检索出错，错误信息【{}】", e.fillInStackTrace());
		}
		return 0;
	}
	public static void main(String[] args) throws ParseException {
//		Client esClient = null;
//		Calendar cal=Calendar.getInstance();
//		cal.add(Calendar.HOUR_OF_DAY, -24);
//		esClient = new ESClient("Media-University","1.119.44.201", 9300).getClient();
//		SearchRequestBuilder srb = esClient.prepareSearch("mediaspider*");
//		BoolQueryBuilder bb = new BoolQueryBuilder();
//		srb.setQuery(bb);
//		QueryBuilder matchQuery = QueryBuilders.matchPhraseQuery("type", "今日头条");
//		bb.should(matchQuery);
//		srb.setSize(1);
//		srb.setPostFilter(QueryBuilders.rangeQuery("time").gte(getNeedTime(cal)).lte(getNeedTime(Calendar.getInstance())));
//		SearchResponse response = srb.execute().actionGet();
//		SearchHits searchHits = response.getHits();
//		System.out.println(searchHits.getTotalHits());
		
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
		for(Map<String,Object> map: getDatasMap("1.119.44.201", 9300, "Media-University", "mediaspider*"
				, 20, "UrlListDetailb174e638-69f9-4b92-9468-786c274bbfee", "平媒")) {
			System.out.println(map.get("title"));
			String date = map.get("time").toString().replace("Z", " UTC");
//			System.out.println(map.get("time"));
			System.out.println(sdf.parse(date));
			System.out.println((long)map.get("savetime"));
			
		}
	}
	
	/**
	 * 数据查询。获取数据
	 * 
	 * @param start
	 * @param end
	 * @param pt
	 * @param type
	 * @param value
	 * @param spyderInfoId
	 * @return
	 */
	public static List<Map<String, Object>> getDatasMap(String host, int port, String dbNamel, String collection, int count,
			String id,String pt) {
		List<Map<String,Object>> list=new ArrayList<>();
		Client esClient=null;
		Calendar cal=Calendar.getInstance();
		cal.add(Calendar.DATE, -7);
		try {
			if (DbDepot.esClients==null||DbDepot.esClients.get(pt) == null) {
				esClient = new ESClient(dbNamel, host, port).getClient();
//				DbDepot.esClients.put(pt, esClient);
			} else {
				esClient = (Client) DbDepot.esClients.get(pt);
			}
			// 搜索数据
			SearchRequestBuilder srb = esClient.prepareSearch(collection);
			srb.setPostFilter(QueryBuilders.rangeQuery("time").gte(getNeedTime(cal)).lte(getNeedTime(Calendar.getInstance())));
			BoolQueryBuilder bb = new BoolQueryBuilder();
			QueryBuilder matchQuery = QueryBuilders.matchPhraseQuery("spyderInfoId",id);
			bb.should(matchQuery);
			srb.setQuery(bb);
			srb.setSize(count);
			SearchResponse response = srb.execute().actionGet();
			SearchHits searchHits = response.getHits();
			for(SearchHit result:searchHits) {
				Map<String,Object> map=result.getSource();
				list.add(map);
			}
		} catch (Exception e) {
			log.error("es检索出错，错误信息【{}】", e.fillInStackTrace());
		}
		return list;
	}

	public static String getNeedTime(Calendar cal) {
		Calendar time=Calendar.getInstance();
		time.setTime(cal.getTime());
		time.add(Calendar.HOUR_OF_DAY, -8);
		String result="";
		result=sdf.format(time.getTime())+"T"
		+(time.get(Calendar.HOUR_OF_DAY)>=10?time.get(Calendar.HOUR_OF_DAY):"0"+time.get(Calendar.HOUR_OF_DAY)
		+":00:00.000Z");
		return result;
	}
	
	/**
	 * 根据时间和参数查询具体数据量
	 * @param start
	 * @param end
	 * @param method
	 * @param param
	 * @param ser
	 * @return
	 */
	public List<Data> findByMethodAndParam(CrawTemplateService crService,Date start, Date end, String method, String param, ServerBean ser) {
		List<Data> list=new ArrayList<>();
		Calendar startTime = Calendar.getInstance();
		startTime.setTime(start);
		Calendar endTime = Calendar.getInstance();
		endTime.setTime(end);
		String key="";
		String value="";
		if(method.equals("tempName")) {
			key="spyderInfoId";
			value = crService.getSpIdByConfigName(param);
		}else {
			key=method;
			value=param;
		}
		Client esClient = null;
		try {
			if (DbDepot.esClients.get(ser.getPt()) == null) {
				esClient = new ESClient(ser.getDbName(), ser.getDbHost(), ser.getDbPort()).getClient();
				DbDepot.esClients.put(ser.getPt(), esClient);
			} else {
				esClient = (Client) DbDepot.esClients.get(ser.getPt());
			}
			Calendar loopTime=Calendar.getInstance();
			loopTime.setTime(startTime.getTime());
			loopTime.add(Calendar.HOUR_OF_DAY, 1);
			endTime.add(Calendar.HOUR_OF_DAY, 1);//n+1
			SearchRequestBuilder srb = esClient.prepareSearch(ser.getCollection());
			BoolQueryBuilder bb = new BoolQueryBuilder();
			QueryBuilder matchQuery = QueryBuilders.matchPhraseQuery(key, value);
			bb.should(matchQuery);
			srb.setQuery(bb);
			srb.setSize(1);
			while (startTime.getTime().before(endTime.getTime())) {
				// 搜索数据
				srb.setPostFilter(QueryBuilders.rangeQuery("time").gte(getNeedTime(startTime)).lte(getNeedTime(loopTime)));
				SearchResponse response = srb.execute().actionGet();
				Data data=new Data();
				data.setSource(method);
				data.setCount(response.getHits().getTotalHits());
				data.setTime(startTime.getTime());
				list.add(data);
				startTime.add(Calendar.HOUR_OF_DAY, 1);
				loopTime.add(Calendar.HOUR_OF_DAY, 1);
			}
		} catch (Exception e) {
			log.error("es检索出错，错误信息【{}】", e.fillInStackTrace());
		}
		return list;
	}

	public int getCounts(Date start, Date end, String pt, String value, String spid, ServerBean ser) {
		Calendar startTime = Calendar.getInstance();
		startTime.setTime(start);
		Calendar endTime = Calendar.getInstance();
		endTime.setTime(end);
		Client esClient=null;
		
		for(int i=0;i<3;i++) {
			try {
				esClient = getClient(pt, ser);
				// 搜索数据
				SearchRequestBuilder srb = esClient.prepareSearch(ser.getCollection());
				BoolQueryBuilder bb = new BoolQueryBuilder();
				srb.setQuery(bb);
				srb.setPostFilter(QueryBuilders.rangeQuery("time").gte(getNeedTime(startTime)).lte(getNeedTime(endTime)));
				QueryBuilder matchQuery = QueryBuilders.matchPhraseQuery("spyderInfoId", spid);
				bb.should(matchQuery);
				srb.setSize(1);
				SearchResponse response = srb.execute().actionGet();
				SearchHits searchHits = response.getHits();
				if(searchHits!=null) {
					return (int) searchHits.getTotalHits();
				}
				return 0;
			} catch (Exception e) {
				log.error("es检索出错，错误信息【{}】", e.fillInStackTrace());
				continue;
			}
		}
		return 0;
	}

	/**
	 * 获取数量
	 * 
	 * @param start
	 * @param end
	 * @param pt
	 * @param value
	 * @return
	 */
	public int getCountByPt(Date start, Date end, String pt, String value, ServerBean ser) {
		Calendar startTime = Calendar.getInstance();
		startTime.setTime(start);
		startTime.add(Calendar.HOUR, -8);
		Calendar endTime = Calendar.getInstance();
		endTime.setTime(end);
		endTime.add(Calendar.HOUR, -8);
		Client esClient=null;
		for(int i=0;i<3;i++) {
			try {
				esClient = getClient(pt, ser);
				// 搜索数据
				SearchRequestBuilder srb = esClient.prepareSearch(ser.getCollection());
				BoolQueryBuilder bb = new BoolQueryBuilder();
				srb.setQuery(bb);
				addQuerys(pt, startTime, endTime, srb, bb);
				srb.setSize(1);
				SearchResponse response = srb.execute().actionGet();
				SearchHits searchHits = response.getHits();
				if(searchHits!=null) {
					return (int) searchHits.getTotalHits();
				}
				return 0;
			} catch (Exception e) {
				log.error("es检索出错，错误信息【{}】", e.fillInStackTrace());
				continue;
			}
		}
		
		return 0;
	}

	private synchronized Client getClient(String pt, ServerBean ser) {
		Client esClient;
		if (DbDepot.esClients.get(pt) == null) {
			esClient = new ESClient(ser.getDbName(), ser.getDbHost(), ser.getDbPort()).getClient();
			DbDepot.esClients.put(ser.getPt(), esClient);
		} else {
			esClient = (Client) DbDepot.esClients.get(pt);
		}
		return esClient;
	}

	private static void addQuerys(String pt, Calendar startTime, Calendar endTime, SearchRequestBuilder srb,
			BoolQueryBuilder bb) {
		if (pt.equals("微博")) {
			srb.setPostFilter(QueryBuilders.rangeQuery("ins").gte(sendTime(startTime)).lt(sendTime(endTime)));
		} else if (pt.equals("知乎")) {
			srb.setPostFilter(QueryBuilders.rangeQuery("insert_at").gte(sendTime(startTime)).lt(sendTime(endTime)));
		} else if (pt.equals("微信全量")) {
			srb.setPostFilter(QueryBuilders.rangeQuery("time").gte(sendTime(startTime)).lt(sendTime(endTime)));
		} else if (pt.equals("今日头条")) {
			srb.setPostFilter(QueryBuilders.rangeQuery("time").gte(sendTime(startTime)).lt(sendTime(endTime)));
			QueryBuilder matchQuery = QueryBuilders.matchPhraseQuery("type", pt);
			bb.should(matchQuery);
		} else if (pt.equals("客户端")) {
			srb.setPostFilter(QueryBuilders.rangeQuery("time").gte(sendTime(startTime)).lt(sendTime(endTime)));
			QueryBuilder matchQuery = QueryBuilders.wildcardQuery("type", "*客户端");
			QueryBuilder matchQuery2 = QueryBuilders.wildcardQuery("type", "脉脉");
			bb.should(matchQuery2);
			bb.should(matchQuery);
		} else {
			srb.setPostFilter(QueryBuilders.rangeQuery("time").gte(sendTime(startTime)).lt(sendTime(endTime)));
			QueryBuilder matchQuery = QueryBuilders.matchPhraseQuery("pt", pt);
			QueryBuilder matchQuery2 = QueryBuilders.matchPhraseQuery("type", pt);
			bb.should(matchQuery);
			bb.should(matchQuery2);
		}
	}

	public static String sendTime(Calendar time) {
		return sdf.format(time.getTime()) + "T"
				+ (time.get(Calendar.HOUR_OF_DAY) >= 10 ? time.get(Calendar.HOUR_OF_DAY) + ""
						: "0" + time.get(Calendar.HOUR_OF_DAY))
				+ ":00:00.000Z";
	}
}
