package com.gyee.frame.util.taos;

import com.alibaba.fastjson.JSONObject;
import com.gyee.frame.common.spring.InitialRunner;
import com.gyee.frame.model.auto.WindPowerStationTestingPoint;
import com.gyee.frame.model.auto.WindTurbineTestingPointAi;
import com.gyee.frame.model.custom.DNAStatVal;
import com.gyee.frame.model.custom.DNAVal;
import com.gyee.frame.model.custom.PointData;
import com.gyee.frame.util.IRealTimeDataBaseUtil;
import com.gyee.frame.util.StringUtils;
import com.gyee.frame.util.golden.timeseries.ErrorRequest;
import org.springframework.web.client.RestTemplate;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.*;


/**
 */
public class TaosUtil implements IRealTimeDataBaseUtil {

	private RestTemplate restTemplate = new RestTemplate();
	private SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


	@Override
	public PointData getRealData(WindPowerStationTestingPoint point) throws Exception {

		PointData po = null;
		if (StringUtils.notEmp(point) && StringUtils.notEmp(point.getCode())) {

			Connection conn = ApiTaos.getInstance();

			String pointId = point.getCode();
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT LAST_ROW(*)  FROM  ");
					sb.append(pointId).append(" ;");

					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp(1);
							value =resultSet.getDouble(2);;
							po = new PointData();
							po.setEdnaId(point.getCode());
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);

						}

					} catch (SQLException e) {
						e.printStackTrace();
					}
				}

			}

		}
		return po;
	}

	@Override
	public List<PointData> getHistoryDatasSnap(WindPowerStationTestingPoint point, Long beginDate, Long endDate, Long count, Long pried) throws Exception {

		// 通过时间区间和时间间隔获取点数
		Long finalInterval;
		if (pried != null)
			finalInterval = pried;
		else if (count != null)
			finalInterval = (endDate - beginDate) / count;
		else
			return ErrorRequest.RequestListError(point.getCode());

		Optional<Integer> interval = Optional.ofNullable(Integer.parseInt(finalInterval.toString()));

		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(point) && StringUtils.notEmp(point.getCode()) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(count) && StringUtils.notEmp(endDate) && StringUtils.notEmp(pried)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = point.getCode();
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));

					sb.setLength(0);
					sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append("  where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");
					sb.append(" INTERVAL(").append(interval.get()).append("s)");
					sb.append(" FILL(PREV) ");
					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));

					try {

						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("ts");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(point.getCode());
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}

					if (vos.isEmpty()) {

						Calendar ca = Calendar.getInstance();
						ca.setTimeInMillis(beginDate * 1000);
						Date end = ca.getTime();
						ca.add(Calendar.YEAR, -1);
						Date begin = ca.getTime();
						sb.setLength(0);
						sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
						sb.append(pointId);
						sb.append("  where point_time>='").append(df.format(begin));
						sb.append("' and point_time<'").append(df.format(end)).append("' ");

						resultSet = stmt.executeQuery(String.valueOf(sb));
						ca.setTimeInMillis(beginDate * 1000);
						double value = 0.0;
						try {
							while (resultSet.next()) {
								value = resultSet.getDouble("value_double");
							}

						} catch (SQLException e) {
							e.printStackTrace();
						}

						if (pried != null && pried != 0) {
							count = (endDate - beginDate) / pried;
						}

						for (int i = 0; i < count; i++) {
							PointData po = new PointData();
							po.setEdnaId(point.getCode());
							po.setPointTime(ca.getTimeInMillis() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
							ca.add(Calendar.SECOND, finalInterval.intValue());
						}
					}

				}
			}
		}
		return vos;

	}



	@Override
	public List<PointData> getHistoryDatasRaw(WindPowerStationTestingPoint point, Long beginDate, Long endDate) throws Exception {

		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(point) && StringUtils.notEmp(point.getCode()) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(endDate)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = point.getCode();
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append(" where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");

					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("point_time");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(point.getCode());
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}

					} catch (SQLException e) {
						e.printStackTrace();
					}
				}

			}

		}
		return vos;
	}

	@Override
	public PointData getRealData(WindTurbineTestingPointAi point) throws Exception {
		PointData po = null;
		if (StringUtils.notEmp(point) && StringUtils.notEmp(point.getId())) {

			Connection conn = ApiTaos.getInstance();

			String pointId = point.getId();
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT LAST_ROW(*)  FROM  ");
					sb.append(pointId);

					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("point_time");
							value = resultSet.getDouble("value_double");
							po = new PointData();
							po.setEdnaId(point.getCode());
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);

						}

					} catch (SQLException e) {
						e.printStackTrace();
					}
				}

			}

		}
		return po;
	}

	@Override
	public List<PointData> getHistoryDatasSnap(WindTurbineTestingPointAi point, Long beginDate, Long endDate, Long count, Long pried) throws Exception {
		// 通过时间区间和时间间隔获取点数
		Long finalInterval;
		if (pried != null)
			finalInterval = pried;
		else if (count != null)
			finalInterval = (endDate - beginDate) / count;
		else
			return ErrorRequest.RequestListError(point.getId());

		Optional<Integer> interval = Optional.ofNullable(Integer.parseInt(finalInterval.toString()));

		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(point) && StringUtils.notEmp(point.getId()) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(count) && StringUtils.notEmp(endDate) && StringUtils.notEmp(pried)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = point.getId();
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append("  where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");
					sb.append(" INTERVAL(").append(interval.get()).append("s)");
					sb.append(" FILL(PREV) ");
					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("ts");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(point.getId());
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}

					if (vos.isEmpty()) {

						Calendar ca = Calendar.getInstance();
						ca.setTimeInMillis(beginDate * 1000);
						Date end = ca.getTime();
						ca.add(Calendar.YEAR, -1);
						Date begin = ca.getTime();
						sb.setLength(0);
						sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
						sb.append(pointId);
						sb.append("  where point_time>='").append(df.format(begin));
						sb.append("' and point_time<'").append(df.format(end)).append("' ");

						resultSet = stmt.executeQuery(String.valueOf(sb));
						ca.setTimeInMillis(beginDate * 1000);
						double value = 0.0;
						try {
							while (resultSet.next()) {
								value = resultSet.getDouble("value_double");
							}

						} catch (SQLException e) {
							e.printStackTrace();
						}

						if (pried != null && pried != 0) {
							count = (endDate - beginDate) / pried;
						}

						for (int i = 0; i < count; i++) {
							PointData po = new PointData();
							po.setEdnaId(point.getId());
							po.setPointTime(ca.getTimeInMillis() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
							ca.add(Calendar.SECOND, finalInterval.intValue());
						}
					}

				}
			}
		}
		return vos;
	}


	@Override
	public List<PointData> getHistoryDatasRaw(WindTurbineTestingPointAi point, Long beginDate, Long endDate) throws Exception {
		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(point) && StringUtils.notEmp(point.getId()) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(endDate)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = point.getId();
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append(" where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");

					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("point_time");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(point.getId());
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}

			}

		}
		return vos;
	}

	@Override
	public PointData getRealData(String pointid) throws Exception {
		PointData po = null;
		if (StringUtils.notEmp(pointid)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = pointid;
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT LAST_ROW(*)  FROM  ");
					sb.append(pointId);

					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp(1);
							value = resultSet.getDouble(2);
							po = new PointData();
							po.setEdnaId(pointid);
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);

						}

					} catch (SQLException e) {
						e.printStackTrace();
					}
				}

			}

		}
		return po;
	}

	@Override
	public List<PointData> getRealData(String... pointids) throws Exception {

		List<PointData> vos = new ArrayList<>();
		if (null != pointids && pointids.length > 0) {
			for (int i = 0; i < pointids.length; i++) {
				getRealData(pointids[i]);
			}
		}
		return vos;
	}

	@Override
	public List<PointData> getRealData(List<String> pointids) throws Exception {

		List<PointData> vos = new ArrayList<>();
		if (null != pointids && pointids.size() > 0) {
			for (int i = 0; i < pointids.size(); i++) {
				getRealData(pointids.get(i));
			}
		}
		return vos;
	}

	@Override
	public Map<String, Double> getRealDataMap(String... pointids) throws Exception {
		Map<String, Double> map = new HashMap<>();
		if (null != pointids && pointids.length > 0) {
			for (int i = 0; i < pointids.length; i++) {
				PointData po = getRealData(pointids[i]);
				map.put(po.getEdnaId(), po.getPointValueInDouble());
			}
		}
		return map;
	}

	@Override
	public List<PointData> getHistoryDatasSnap(String pointid, Long beginDate, Long endDate, Long count, Long pried) throws Exception {
		// 通过时间区间和时间间隔获取点数
		Long finalInterval;
		if (pried != null)
			finalInterval = pried;
		else if (count != null)
			finalInterval = (endDate - beginDate) / count;
		else
			return ErrorRequest.RequestListError(pointid);

		Optional<Integer> interval = Optional.ofNullable(Integer.parseInt(finalInterval.toString()));

		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(pointid) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(count) && StringUtils.notEmp(endDate) && StringUtils.notEmp(pried)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = pointid;
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append("  where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");
					sb.append(" INTERVAL(").append(interval.get()).append("s)");
					sb.append(" FILL(PREV) ");
					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));

					try {

						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("ts");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(pointid);
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}

					} catch (SQLException e) {
						e.printStackTrace();
					}

					if (vos.isEmpty()) {

						Calendar ca = Calendar.getInstance();
						ca.setTimeInMillis(beginDate * 1000);
						Date end = ca.getTime();
						ca.add(Calendar.YEAR, -1);
						Date begin = ca.getTime();
						sb.setLength(0);
						sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
						sb.append(pointId);
						sb.append("  where point_time>='").append(df.format(begin));
						sb.append("' and point_time<'").append(df.format(end)).append("' ");

						resultSet = stmt.executeQuery(String.valueOf(sb));
						ca.setTimeInMillis(beginDate * 1000);
						double value = 0.0;
						try {
							while (resultSet.next()) {
								value = resultSet.getDouble("value_double");
							}

						} catch (SQLException e) {
							e.printStackTrace();
						}

						if (pried != null && pried != 0) {
							count = (endDate - beginDate) / pried;
						}

						for (int i = 0; i < count; i++) {
							PointData po = new PointData();
							po.setEdnaId(pointid);
							po.setPointTime(ca.getTimeInMillis() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
							ca.add(Calendar.SECOND, finalInterval.intValue());
						}
					}

				}
			}
		}
		return vos;
	}



	@Override
	public List<PointData> getHistoryDatasRaw(String pointid, Long beginDate, Long endDate) throws Exception {
		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(pointid) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(endDate)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = pointid;
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append(" where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");

					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("point_time");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(pointid);
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}

			}

		}
		return vos;
	}

	@Override
	public List<PointData> getHistStat(WindTurbineTestingPointAi point, Long beginDate, Long endDate, Long count, Long pried, int type) throws Exception {
		// 通过时间区间和时间间隔获取点数
		Long finalInterval;
		if (pried != null)
			finalInterval = pried;
		else if (count != null)
			finalInterval = (endDate - beginDate) / count;
		else
			return ErrorRequest.RequestListError(point.getId());

		Optional<Integer> interval = Optional.ofNullable(Integer.parseInt(finalInterval.toString()));

		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(point) && StringUtils.notEmp(point.getId()) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(count) && StringUtils.notEmp(endDate) && StringUtils.notEmp(pried) && StringUtils.notEmp(type)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = point.getId();
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT point_time,");
					switch (type) {
					case 0:
						sb.append("MAX");
						break;
					case 1:
						sb.append("MIN");
						break;
					case 2:
						sb.append("AVG");
						break;
					default:
						break;
					}

					sb.append("(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append("  where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");
					sb.append(" INTERVAL(").append(interval.get()).append("s)");
					sb.append(" FILL(PREV) ");
					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("ts");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(point.getId());
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}

					if (vos.isEmpty()) {

						Calendar ca = Calendar.getInstance();
						ca.setTimeInMillis(beginDate * 1000);
						Date end = ca.getTime();
						ca.add(Calendar.YEAR, -1);
						Date begin = ca.getTime();
						sb.setLength(0);
						sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
						sb.append(pointId);
						sb.append("  where point_time>='").append(df.format(begin));
						sb.append("' and point_time<'").append(df.format(end)).append("' ");

						resultSet = stmt.executeQuery(String.valueOf(sb));
						ca.setTimeInMillis(beginDate * 1000);
						double value = 0.0;
						try {
							while (resultSet.next()) {
								value = resultSet.getDouble("value_double");
							}

						} catch (SQLException e) {
							e.printStackTrace();
						}

						if (pried != null && pried != 0) {
							count = (endDate - beginDate) / pried;
						}

						for (int i = 0; i < count; i++) {
							PointData po = new PointData();
							po.setEdnaId(point.getId());
							po.setPointTime(ca.getTimeInMillis() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
							ca.add(Calendar.SECOND, finalInterval.intValue());
						}
					}

				}
			}
		}
		return vos;
	}

	@Override
	public List<PointData> getHistStat(WindPowerStationTestingPoint point, Long beginDate, Long endDate, Long count, Long pried, int type) throws Exception {

		// 通过时间区间和时间间隔获取点数
		Long finalInterval;
		if (pried != null)
			finalInterval = pried;
		else if (count != null)
			finalInterval = (endDate - beginDate) / count;
		else
			return ErrorRequest.RequestListError(point.getCode());

		Optional<Integer> interval = Optional.ofNullable(Integer.parseInt(finalInterval.toString()));

		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(point) && StringUtils.notEmp(point.getCode()) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(count) && StringUtils.notEmp(endDate) && StringUtils.notEmp(pried) && StringUtils.notEmp(type)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = point.getCode();
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT point_time,");
					switch (type) {
					case 0:
						sb.append("MAX");
						break;
					case 1:
						sb.append("MIN");
						break;
					case 2:
						sb.append("AVG");
						break;
					default:
						break;
					}

					sb.append("(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append("  where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");
					sb.append(" INTERVAL(").append(interval.get()).append("s)");
					sb.append(" FILL(PREV) ");
					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("ts");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(point.getCode());
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}

					if (vos.isEmpty()) {

						Calendar ca = Calendar.getInstance();
						ca.setTimeInMillis(beginDate * 1000);
						Date end = ca.getTime();
						ca.add(Calendar.YEAR, -1);
						Date begin = ca.getTime();
						sb.setLength(0);
						sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
						sb.append(pointId);
						sb.append("  where point_time>='").append(df.format(begin));
						sb.append("' and point_time<'").append(df.format(end)).append("' ");

						resultSet = stmt.executeQuery(String.valueOf(sb));
						ca.setTimeInMillis(beginDate * 1000);
						double value = 0.0;
						try {
							while (resultSet.next()) {
								value = resultSet.getDouble("value_double");
							}

						} catch (SQLException e) {
							e.printStackTrace();
						}

						if (pried != null && pried != 0) {
							count = (endDate - beginDate) / pried;
						}

						for (int i = 0; i < count; i++) {
							PointData po = new PointData();
							po.setEdnaId(point.getCode());
							po.setPointTime(ca.getTimeInMillis() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
							ca.add(Calendar.SECOND, finalInterval.intValue());
						}
					}

				}
			}
		}
		return vos;
	}

	@Override
	public List<PointData> getHistStat(String pointid, Long beginDate, Long endDate, Long count, Long pried, int type) throws Exception {
		// 通过时间区间和时间间隔获取点数
		Long finalInterval;
		if (pried != null)
			finalInterval = pried;
		else if (count != null)
			finalInterval = (endDate - beginDate) / count;
		else
			return ErrorRequest.RequestListError(pointid);

		Optional<Integer> interval = Optional.ofNullable(Integer.parseInt(finalInterval.toString()));

		List<PointData> vos = new ArrayList<>();

		if (StringUtils.notEmp(pointid) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(count) && StringUtils.notEmp(endDate) && StringUtils.notEmp(pried) && StringUtils.notEmp(type)) {

			Connection conn = ApiTaos.getInstance();

			String pointId = pointid;
			String prostr = pointId.substring(0, pointId.indexOf("."));
			pointId = pointId.replace(".", "_");
			if (null != conn) {
				Statement stmt = conn.createStatement();

				if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
					String databases = InitialRunner.taosmap.get(prostr);

					// 选择数据库
					StringBuilder sb = new StringBuilder();
					sb.append("use ").append(databases);
					stmt.executeUpdate(String.valueOf(sb));
					sb.setLength(0);
					sb.append(" SELECT point_time,");
					switch (type) {
					case 0:
						sb.append("MAX");
						break;
					case 1:
						sb.append("MIN");
						break;
					case 2:
						sb.append("AVG");
						break;
					default:
						break;
					}

					sb.append("(value_double) as  value_double FROM  ");
					sb.append(pointId);
					sb.append("  where point_time>='").append(df.format(beginDate * 1000));
					sb.append("' and point_time<'").append(df.format(endDate * 1000)).append("' ");
					sb.append(" INTERVAL(").append(interval.get()).append("s)");
					sb.append(" FILL(PREV) ");
					ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));
					try {
						while (resultSet.next()) {

							Timestamp ts = null;
							double value = 0;

							ts = resultSet.getTimestamp("ts");
							value = resultSet.getDouble("value_double");
							PointData po = new PointData();
							po.setEdnaId(pointid);
							po.setPointTime(ts.getTime() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}

					if (vos.isEmpty()) {

						Calendar ca = Calendar.getInstance();
						ca.setTimeInMillis(beginDate * 1000);
						Date end = ca.getTime();
						ca.add(Calendar.YEAR, -1);
						Date begin = ca.getTime();
						sb.setLength(0);
						sb.append(" SELECT point_time,LAST_ROW(value_double) as  value_double FROM  ");
						sb.append(pointId);
						sb.append("  where point_time>='").append(df.format(begin));
						sb.append("' and point_time<'").append(df.format(end)).append("' ");

						resultSet = stmt.executeQuery(String.valueOf(sb));
						ca.setTimeInMillis(beginDate * 1000);
						double value = 0.0;
						try {
							while (resultSet.next()) {
								value = resultSet.getDouble("value_double");
							}

						} catch (SQLException e) {
							e.printStackTrace();
						}

						if (pried != null && pried != 0) {
							count = (endDate - beginDate) / pried;
						}

						for (int i = 0; i < count; i++) {
							PointData po = new PointData();
							po.setEdnaId(pointid);
							po.setPointTime(ca.getTimeInMillis() / 1000);
							po.setPointValueInDouble(value);
							vos.add(po);
							ca.add(Calendar.SECOND, finalInterval.intValue());
						}
					}

				}
			}
		}
		return vos;
	}

	@Override
	public DNAStatVal[] getHistStat(String pointid, Long beginDate, Long endDate, Integer pried) throws Exception {

		// 通过时间区间和时间间隔获取点数
		Long finalInterval = Long.valueOf(pried);
		Long count = 0l;

		List<DNAStatVal> list = new ArrayList<>();
		if (StringUtils.notEmp(pointid) && StringUtils.notEmp(beginDate) && StringUtils.notEmp(count) && StringUtils.notEmp(endDate) && StringUtils.notEmp(pried)) {

			if (finalInterval != 0) {
				count = (endDate - beginDate) / finalInterval;
			}

			List<PointData> maxls = getHistStat(pointid, beginDate, endDate, count, finalInterval, 0);
			List<PointData> minls = getHistStat(pointid, beginDate, endDate, count, finalInterval, 0);
			List<PointData> avgls = getHistStat(pointid, beginDate, endDate, count, finalInterval, 0);

			if (!maxls.isEmpty() && !minls.isEmpty() && !avgls.isEmpty() && maxls.size() == minls.size() && maxls.size() == avgls.size()) {
				for (int i = 0; i < maxls.size(); i++) {
					PointData maxpo = maxls.get(i);
					PointData minpo = minls.get(i);
					PointData avgpo = avgls.get(i);

					DNAStatVal statVal = new DNAStatVal();

					DNAVal avgVal = new DNAVal();
					DNAVal maxVal = new DNAVal();
					DNAVal minVal = new DNAVal();

					avgVal.Time = Integer.valueOf(String.valueOf(avgpo.getPointTime() / 1000));
					avgVal.DValue = Double.valueOf(avgpo.getPointValueInDouble());

					maxVal.Time = Integer.valueOf(String.valueOf(maxpo.getPointTime() / 1000));
					maxVal.DValue = Double.valueOf(maxpo.getPointValueInDouble());

					minVal.Time = Integer.valueOf(String.valueOf(minpo.getPointTime() / 1000));
					minVal.DValue = Double.valueOf(minpo.getPointValueInDouble());

					statVal.max = maxVal;
					statVal.min = minVal;
					statVal.avg = avgVal;

					list.add(statVal);
				}
				DNAStatVal[] arr = new DNAStatVal[list.size()];
				return list.toArray(arr);
			}

		}
		return null;
	}

	private JSONObject convertPointData(PointData pd) {
		JSONObject jo = new JSONObject();
		jo.put("tagName", pd.getEdnaId());
		JSONObject joo = new JSONObject();
		joo.put("ts", pd.getPointTime() * 1000);
		joo.put("status", 0);
		joo.put("doubleValue", pd.getPointValueInDouble());
		jo.put("tsData", joo);
		return jo;
	}

	@Override
	public void updatePoint(PointData point) throws Exception {

	}

	@Override
	public DNAVal[] getRealtimeTagValues(String... tagNames) throws Exception {

		DNAVal[] result = new DNAVal[tagNames.length];

		if (tagNames.length > 0) {
			for (int i = 0; i < tagNames.length; i++) {
				PointData po = getRealData(tagNames[i]);
				DNAVal val = new DNAVal();
				val.Status = 1;
				val.DValue = po.getPointValueInDouble();
				val.Time = Integer.valueOf(String.valueOf(po.getPointTime() / 1000));
				result[i] = val;

			}
		}
		return result;
	}

	@Override
	public void updatePoint(List<PointData> pointls) throws Exception {

	}



	// 多点切面数据
	@Override
    public DNAVal[] getHistMatrix(String[] pointids, long tTime) throws Exception {

		DNAVal[] result = new DNAVal[pointids.length];
		if (StringUtils.notEmp(pointids) && StringUtils.notEmp(tTime)) {

			long time = Long.valueOf(tTime) * 1000;

			Connection conn = ApiTaos.getInstance();

			if (null != conn) {
				Statement stmt = conn.createStatement();

				Calendar ca = Calendar.getInstance();
				ca.setTimeInMillis(time);

				for (int i = 0; i < pointids.length; i++) {

					String pointid = pointids[i];

					String pointId = pointid;
					String prostr = pointId.substring(0, pointId.indexOf("."));
					pointId = pointId.replace(".", "_");

					if (StringUtils.notEmp(prostr) && InitialRunner.taosmap.containsKey(prostr)) {
						String databases = InitialRunner.taosmap.get(prostr);

						// 选择数据库
						StringBuilder sb = new StringBuilder();
						sb.append("use ").append(databases);
						stmt.executeUpdate(String.valueOf(sb));

						Date end = ca.getTime();
						ca.set(Calendar.YEAR, -1);
						Date begin = ca.getTime();

						ResultSet resultSet = findValue(stmt, df, pointId, begin, end);
						if (resultSet.next()) {

							setDvalValue(result, i, resultSet);
						} else {

							DNAVal dval = new DNAVal();
							dval.DValue = 0.0;
							dval.Time = Integer.valueOf(String.valueOf(tTime));
							result[i] = dval;
							//
							// ca.setTimeInMillis(time);
							//
							// end = ca.getTime();
							// ca.set(Calendar.DAY_OF_MONTH, -1);
							// begin = ca.getTime();
							//
							// resultSet = findValue(stmt, df, pointId, begin,
							// end);
							// if (resultSet.next()) {
							// setDvalValue(result, i, resultSet);
							//
							// } else {
							//
							// ca.setTimeInMillis(time);
							//
							// end = ca.getTime();
							// ca.set(Calendar.MONTH, -1);
							// begin = ca.getTime();
							//
							// resultSet = findValue(stmt, df, pointId, begin,
							// end);
							// if (resultSet.next()) {
							// setDvalValue(result, i, resultSet);
							//
							// } else {
							// ca.setTimeInMillis(time);
							//
							// end = ca.getTime();
							// ca.set(Calendar.YEAR, -1);
							// begin = ca.getTime();
							//
							// resultSet = findValue(stmt, df, pointId, begin,
							// end);
							// if (resultSet.next()) {
							// setDvalValue(result, i, resultSet);
							//
							// }
							// }
							// }
						}

					}

				}
			}

		}

		return result;
	}

	private void setDvalValue(DNAVal[] result, int i, ResultSet resultSet) throws SQLException {
		Timestamp ts = null;
		double value = 0;
		ts = resultSet.getTimestamp("point_time");
		value = resultSet.getDouble("value_double");
		DNAVal dval = new DNAVal();
		dval.DValue = value;
		dval.Time = Integer.valueOf(String.valueOf(ts.getTime() / 1000));
		result[i] = dval;
	}

	private ResultSet findValue(Statement stmt, SimpleDateFormat df, String id, Date begin, Date end) throws SQLException {
		StringBuilder sb = new StringBuilder();
		sb.append(" SELECT  point_time,LAST_ROW(value_double) as value_double FROM ").append(id);
		sb.append("  where  point_time>='").append(df.format(begin)).append("' and point_time<='").append(df.format(end)).append("' ");

		ResultSet resultSet = stmt.executeQuery(String.valueOf(sb));

		return resultSet;
	}



}
