package com.saga.thread.common;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.alibaba.fastjson.JSONObject;
import com.saga.util.MessageUtil;
import org.zillion.util.log.LogUtil;

import com.saga.entity.Record;
import com.saga.util.Constant;

/**
 * 数据处理
 *
 * @author 李井强
 */
public class SaveThread extends Thread {
	// private List<String> pointCommunicationList = new ArrayList<String>();
	// private String ip = null;
	private List<String> streportList = new ArrayList<String>();
	private List<Record> strecordList = new ArrayList<Record>();

	public SaveThread() {
		try {
			// this.ip = Constant.getLocalHostLANAddress().getHostAddress() +
			// ":" + Constant.TypePort.get("Down");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			// this.ip = "0.0.0.0" + ":" + Constant.TypePort.get("Down");
			e.printStackTrace();
		}
	}

	public void run() {
		LogUtil.info("SaveThread" + " Starting ...");
		while (true) {
			try {
				// this.insertPointCommunicationLog();
				this.handleCollectReportList2();
				// this.handleCollectReportList1();

				Thread.sleep(1L);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	// private void insertPointCommunicationLog() {
	// // TODO Auto-generated method stub
	//
	// // PointCommunicationLog添加记录
	// try {
	// if (pointCommunicationList.size() > 0) {
	// // LogUtil.info("pointCommunicationList.size: " +
	// // pointCommunicationList.size());
	// // LogUtil.info("InsertPointCommunicationLog begin...");
	// HBaseUtil.InsertPointCommunicationLog(pointCommunicationList);
	// // LogUtil.info("InsertPointCommunicationLog end...");
	// pointCommunicationList = new ArrayList<String>();
	// }
	// } catch (Exception e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	// }

	/**
	 * 报文处理
	 */
	private void handleCollectReportList2() {
		// TODO Auto-generated method stub
		try {
			synchronized (Constant.CollectReportList) {
				if (Constant.CollectReportList.size() > 0) {
					LogUtil.info("Constant.CollectReportList:" + Constant.CollectReportList.size());
					this.streportList.addAll(Constant.CollectReportList);
					Constant.CollectReportList.clear();
					// Constant.CollectReportList = new ArrayList<String>();
					LogUtil.info("Constant.CollectReportList:" + Constant.CollectReportList.size());
					if (Constant.CollectReportList.size() > 0) {
						LogUtil.warn("Constant.CollectReportList:" + Constant.CollectReportList.size());
						Constant.CollectReportList.clear();
						System.gc();
					}

				} else {
					return;
				}
			}
			Constant.collectReportCount += this.streportList.size();
			LogUtil.info("ReportList:" + this.streportList.size());
			int seq = 0;

			while (this.streportList.size() > 0) {
				seq++;
				LogUtil.info("ReportList:" + this.streportList.size() + " seq:" + seq);
				int no = 5000 > this.streportList.size() ? this.streportList.size() : 5000;
				if (no == 5000 || seq > 1) {
					LogUtil.info("ReportList:" + this.streportList.size() + " seq:" + seq);
				}
				String b = this.streportList.get(0).replace("(", "").replace(")", "").replace("", "");
				if (b == null || b.length() == 0) {
					this.streportList.remove(0);
					return;
				}
				b = this.streportList.get(0).replace("(", "").replace(")", "").replace(" ", "").split(";")[0];

				while (Constant.RecordListToDB.size() > 0) {
					LogUtil.info("wait Constant.RecordListToDB progressing ... ");
					if (Constant.RecordListToDB.size() == 0) {
						LogUtil.warn("wait Constant.RecordListToDB end ");
						break;
					} else {
						Thread.sleep(3L);
					}
					Thread.sleep(1L);
				}

				// recordList = new ArrayList<Record>();
				if (this.strecordList.size() > 0) {
					LogUtil.warn("SaveThread.recordList " + this.strecordList.size());
					this.strecordList.clear();
					System.gc();
				}
				Iterator<String> it = this.streportList.iterator();
				int c = 0;
				synchronized (Constant.ps_PointStatusUp) {
					while (it.hasNext()) {
						try {
							String report = it.next().replace("(", "").replace(")", "").replace(" ", "");
							if (c < no) {
								if (report != null) {
									String[] rList = report.replace("(", "").replace(")", "").replace(" ", "")
											.split(";");
									if (rList != null && rList.length > 8) {
										String building = rList[0];
										if (!building.equalsIgnoreCase(b)) {
											continue;
										}
										// String mac = rList[1];
										String function = rList[2];
										Date time = Constant.parse(rList[3]);
										String meter = rList[5];
										int count = Integer.valueOf(rList[6]);
										// String id = rList[4];

										for (int i = 0; i < count; i++) {
											Record record = new Record();
											if ("report".equalsIgnoreCase(function)) {
												record.funcID = Integer.valueOf(rList[7 + 2 * i]);
												record.data = Double.valueOf(rList[8 + 2 * i]);
												// synchronized
												// (Constant.pointListUp) {
												Constant.ps_PointStatusUp.put(
														building + "-" + meter + "." + record.funcID,
														System.currentTimeMillis());
												// }

											} else if ("reportaddtion".equalsIgnoreCase(function)) {
												record.funcID = Integer.valueOf(rList[7 + 3 * i]);
												record.data = Double.valueOf(rList[8 + 3 * i]);
												record.addtion = "null".equalsIgnoreCase(rList[9 + i * 3]) ? ""
														: (rList[9 + i * 3]);
												// synchronized
												// (Constant.pointListUp) {
												Constant.ps_PointStatusUp.put(
														building + "-" + meter + "." + record.funcID,
														System.currentTimeMillis());

												// }
											}

											record.buildingSign = building;
											record.meterSign = meter;
											record.receivetime = time;
											record.receivetime = Constant.getOffSetTime(record);
											record.funcID = Constant.getFunctionConv(record);

											//TODO 往activeMq消息队列里发送消息
											if (Constant.activeMqPointSet.contains(record.buildingSign + "-" + record.meterSign + "-" + record.funcID)) {
												MessageUtil.sendMessage(JSONObject.toJSONString(record));
											}

											if (toDB(record.buildingSign, record.meterSign, record.funcID)) {
												this.strecordList.add(record);
											}
										}
										it.remove();
										// LogUtil.info("HBase.BatchInsert "
										// +
										// report);
									} else {
										it.remove();
									}

								} else {
									it.remove();
								}
							} else {
								break;
							}
							c++;
							// Thread.sleep(1L);
						} catch (Exception e) {
							// TODO Auto-generated catch block
							it.remove();
							LogUtil.error("SaveThread.run.Exception: " + e.toString());
						}
					}
				}

				Constant.RecordListToDB.addAll(this.strecordList);
				Constant.report2DBCount += this.strecordList.size();
				LogUtil.info("Constant.RecordListToDB add " + this.strecordList.size());
				// recordList = new ArrayList<Record>();
				this.strecordList.clear();

				Thread.sleep(1L);

				// Thread.sleep(Constant.Millisecond.SECOND_1);
			}
			if (this.streportList.size() > 0) {
				LogUtil.warn("SaveThread.reportList " + streportList.size());
				this.streportList.clear();
				System.gc();
				LogUtil.warn("SaveThread.reportList " + streportList.size());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			LogUtil.error("SaveThread.run.Exception: " + e.toString());
			// Constant.DBConn = false;
		}
	}

	/**
	 * 是否需要进库
	 * 
	 * @param meterSign
	 */
	private boolean toDB(String buildingSign, String meterSign, int funcID) {
		// TODO Auto-generated method stub
		if (toDB_building(buildingSign) && toDB_Point(buildingSign, meterSign, funcID)) {
			return true;
		}
		return false;
	}

	/**
	 * 是否需要进库
	 * 
	 * @param meterSign
	 * @param buildingSign
	 */
	private boolean toDB_Point(String buildingSign, String meterSign, int funcID) {
		// TODO Auto-generated method stub
		if (Constant.whilte_Points == null || Constant.whilte_Points.size() == 0) {
			return true;
		}
		if (Constant.whilte_Points.containsKey(buildingSign + "-" + meterSign + "-" + funcID)
				|| Constant.whilte_Points.containsKey(buildingSign + "-" + meterSign + "-" + "all")
				|| Constant.whilte_Points.containsKey(buildingSign + "-" + "all" + "-" + "all")
				|| Constant.whilte_Points.containsKey(buildingSign + "-" + "all" + "-" + funcID)) {
			return true;
		}
		return false;
	}

	/**
	 * 是否需要进库
	 */
	private boolean toDB_building(String buildingSign) {
		// TODO Auto-generated method stub
		if (!Constant.black_Buildings.containsKey(buildingSign)) {
			return true;
		}
		return false;
	}

	// private void addPointCommunicationList(String building, String ip, String
	// mac, String point, String id,
	// String receivetime, String addtion) {
	// // TODO Auto-generated method stub
	// this.pointCommunicationList.add(building + ";" + ip + ";" + mac + ";" +
	// point + ";" + "conn/disconn" + ";" + id
	// + ";" + receivetime + ";" + addtion);
	// }

	// private void handleCollectReportList1() {
	// // TODO Auto-generated method stub
	// try {
	// synchronized (Constant.CollectReportList) {
	//
	// if (Constant.CollectReportList.size() > 0) {
	// // LogUtil.info("SaveThread Challenge
	// // Constant.CollectReportList
	// // begin...");
	// // synchronized (Constant.CollectReportList) {
	// // LogUtil.info("SaveThread Challenge
	// // Constant.CollectReportList get...");
	// // LogUtil.info("Constant.CollectReportList.size(): " +
	// // Constant.CollectReportList.size());
	// int no = 5000 > Constant.CollectReportList.size() ?
	// Constant.CollectReportList.size() : 5000;
	// String b = Constant.CollectReportList.get(0).replace("(",
	// "").replace(")", "").replace(" ", "");
	// if (b == null || b.length() == 0) {
	// Constant.CollectReportList.remove(0);
	// return;
	// }
	// b = Constant.CollectReportList.get(0).replace("(", "").replace(")",
	// "").replace(" ", "")
	// .split(";")[0];
	// // if (Constant.RecordListToDB.size() > 0) {
	// // LogUtil.info("wait Constant.RecordListToDB begin");
	// // LogUtil.info("size:" + Constant.RecordListToDB.size()
	// // + "-->0");
	// // }
	// while (Constant.RecordListToDB.size() > 0) {
	// if (Constant.RecordListToDB.size() == 0) {
	// LogUtil.info("wait Constant.RecordListToDB end ");
	// break;
	// } else {
	// Thread.sleep(3L);
	// LogUtil.info(
	// "wait Constant.RecordListToDB.size:" + Constant.RecordListToDB.size() +
	// "-->0");
	// }
	// Thread.sleep(1L);
	// }
	//
	// // List<Record> recordList = new ArrayList<Record>();
	// this.strecordList.clear();
	// Iterator<String> it = Constant.CollectReportList.iterator();
	// int c = 0;
	// while (it.hasNext()) {
	// // LogUtil.info("Constant.CollectReportList deal " + c);
	// try {
	//
	// String report = it.next().replace("(", "").replace(")", "").replace(" ",
	// "");
	// if (c < no) {
	// if (report != null) {
	// String[] rList = report.replace("(", "").replace(")", "").replace(" ",
	// "")
	// .split(";");
	// if (rList != null && rList.length > 8) {
	// String building = rList[0];
	// if (!building.equalsIgnoreCase(b)) {
	// continue;
	// }
	// String mac = rList[1];
	// String function = rList[2];
	// Date time = Constant.parse(rList[3]);
	// String meter = rList[5];
	// int count = Integer.valueOf(rList[6]);
	// // String id = rList[4];
	//
	// for (int i = 0; i < count; i++) {
	// Record record = new Record();
	// if ("report".equalsIgnoreCase(function)) {
	// Constant.collectReportCount++;
	// record.funcID = Integer.valueOf(rList[7 + 2 * i]);
	// record.data = Double.valueOf(rList[8 + 2 * i]);
	// Constant.ps_PointStatusUp.put(
	// building + "-" + mac + "-" + meter + "." + record.funcID,
	// System.currentTimeMillis());
	// // // PointCommunicationLog添加记录
	// // this.pointCommunicationList.add(building
	// // + ";" + this.ip + ";" + mac
	// // + ";" + meter + "." +
	// // record.funcID + ";" +
	// // function + ";" + id
	// // + ";" + rList[3] + ";" + "");
	// } else if ("reportaddtion".equalsIgnoreCase(function)) {
	// Constant.collectReportCount++;
	// record.funcID = Integer.valueOf(rList[7 + 3 * i]);
	// record.data = Double.valueOf(rList[8 + 3 * i]);
	// record.addtion = "null".equalsIgnoreCase(rList[9 + i * 3]) ? ""
	// : (rList[9 + i * 3]);
	// Constant.ps_PointStatusUp.put(
	// building + "-" + mac + "-" + meter + "." + record.funcID,
	// System.currentTimeMillis());
	// // // PointCommunicationLog添加记录
	// // this.pointCommunicationList.add(building
	// // + ";" + this.ip + ";" + mac
	// // + ";" + meter + "." +
	// // record.funcID + ";" +
	// // function + ";" + id
	// // + ";" + rList[3] + ";" +
	// // record.addtion);
	// // HBaseUtil.InsertPointCommunicationLog(Constant.agent,
	// // Constant.BuildingDB.get(building),
	// // building,
	// // Constant.getLocalHostLANAddress().getHostAddress(),
	// // mac,
	// // meter + "." + record.funcID,
	// // function, id, rList[3],
	// // record.addtion);
	//
	// }
	//
	// record.buildingSign = building;
	// record.meterSign = meter;
	// record.receivetime = time;
	//
	// this.strecordList.add(record);
	//
	// }
	// it.remove();
	// // LogUtil.info("HBase.BatchInsert "
	// // +
	// // report);
	// } else {
	// it.remove();
	// }
	//
	// } else {
	// it.remove();
	// }
	// } else {
	// break;
	// }
	// c++;
	// Thread.sleep(1L);
	// } catch (Exception e) {
	// // TODO Auto-generated catch block
	// it.remove();
	// LogUtil.error("SaveThread.run.Exception: " + e.toString());
	// }
	// }
	// }
	// }
	// // LogUtil.info("SaveThread Challenge
	// // Constant.RecordListToDB begin...");
	// Constant.RecordListToDB.addAll(this.strecordList);
	// Constant.report2DBCount += this.strecordList.size();
	// this.strecordList.clear();
	// if (this.strecordList.size() > 0) {
	// this.strecordList = new ArrayList<Record>();
	// System.gc();
	// }
	// // LogUtil.info("SaveThread Challenge
	// // Constant.RecordListToDB realse...");
	// // HBaseUtil.BatchInsert(Constant.agent,
	// // Constant.BuildingDB.get(b), recordList);
	// // }
	// // LogUtil.info("SaveThread Challenge
	// // Constant.CollectReportList
	// // realse...");
	// Thread.sleep(1L);
	//
	// // Thread.sleep(Constant.Millisecond.SECOND_1);
	// } catch (Exception e) {
	// // TODO Auto-generated catch block
	// LogUtil.error("SaveThread.run.Exception: " + e.toString());
	// // Constant.DBConn = false;
	// }
	// }
}
