package com.zhiwei.chendong;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.zhiwei.servlet.MainController;
import com.zhiwei.util.Config;
import com.zw.entity.ExcelFile;
import com.zw.entity.Excels;
import com.zw.entity.Weixin;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import sendmail.SendMailUtil;

public class ExcelReadAndWrite {

	private final static Log log = LogFactory.getLog(ExcelReadAndWrite.class);
	public static Excels e;
	public static boolean cut = false;
	public static String url = Config.getVal("basefile");
	public static boolean runStrat = false;
	public static int cutCount = 0;
	public static String host = Config.getVal("socketIp");
	public static int port = Integer.valueOf(Config.getVal("socketPort"));
	private static MongoForChenDong m = new MongoForChenDong();

	/**
	 * 读取微信转链接的文件
	 * 
	 * @param url
	 * @return
	 */
	public static List<Weixin> readExcels(String url) {
		InputStream stream = null;
		String str = null;
		List<Weixin> list = new ArrayList<>();
		try {
			stream = new FileInputStream(url);
			Workbook rwb = Workbook.getWorkbook(stream);
			Sheet sheet = rwb.getSheet(0);
			for (int i = 1; i < sheet.getRows(); i++) {
				Cell cell = null;
				Weixin w = new Weixin();
				for (int j = 0; j < sheet.getColumns(); j++) {
					cell = sheet.getCell(j, i);
					str = cell.getContents();
					if (sheet.getCell(j, 0).getContents().equals("来源")) {
						w.setSource(str);
					}
					if (sheet.getCell(j, 0).getContents().equals("时间")) {
						w.setTime(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("标题")) {
						w.setTitle(str);
					}
					if (sheet.getCell(j, 0).getContents().equals("地址")) {
						w.setUrl(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("内容")) {
						w.setConetent(str);
						;
					}
					if (sheet.getCell(j, 0).getContents().equals("关键词")) {
						w.setKeyValue(str);
					}
					if (sheet.getCell(j, 0).getContents().equals("阅读数")) {
						w.setRead(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("点赞数")) {
						w.setZan(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("用户昵称")) {
						w.setNickname(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("简介")) {
						w.setJianjie(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("历史标注情况")) {
						w.setHistory(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("长地址")) {
						w.setLongUrl(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("mark")) {
						w.setMark(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("mark_time")) {
						w.setMark_time(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("markname")) {
						w.setMarkname(str == null ? "null" : str);
					}
					if (sheet.getCell(j, 0).getContents().equals("真实阅读数")) {
						w.setTrueRead(str == null ? "null" : str);
					}
				}
				if (w != null) {
					list.add(w);
				}
			}
			stream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 写出转链接的文件
	 * 
	 * @param list
	 * @param mail
	 * @throws Exception
	 */
	public static void write(List<Weixin> list, String mail) throws Exception {
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		String inurl = url + (int) (Math.random() * 99) + sdf.format(cal.getTime()) + ".xls";
		File tempFile = new File(inurl);
		// 若是文件不存在就创建新文件
		if (!tempFile.exists()) {
			tempFile.createNewFile();
		}
		WritableWorkbook workbook = Workbook.createWorkbook(tempFile);
		WritableSheet sheet = workbook.createSheet("table1", 0);
		// 一些临时变量，用于写到excel中
		Label l = null;
		int seq = 0;
		l = new Label(0, seq, "来源");
		sheet.addCell(l);
		l = new Label(1, seq, "时间");
		sheet.addCell(l);
		l = new Label(2, seq, "内容");
		sheet.addCell(l);
		l = new Label(3, seq, "关键词");
		sheet.addCell(l);
		l = new Label(4, seq, "标题");
		sheet.addCell(l);
		l = new Label(5, seq, "地址");
		sheet.addCell(l);
		l = new Label(6, seq, "获取的地址");
		sheet.addCell(l);
		for (Weixin w : list) {
			seq++;
			l = new Label(0, seq, w.getSource());
			sheet.addCell(l);
			l = new Label(1, seq, w.getTime());
			sheet.addCell(l);
			l = new Label(2, seq, w.getConetent());
			sheet.addCell(l);
			l = new Label(3, seq, w.getKeyValue());
			sheet.addCell(l);
			l = new Label(4, seq, w.getTitle());
			sheet.addCell(l);
			l = new Label(5, seq, w.getUrl());
			sheet.addCell(l);
			l = new Label(6, seq, w.getGetUrl());
			sheet.addCell(l);
		}
		int column = 0;
		sheet.setColumnView(column++, 20);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 30);
		sheet.setColumnView(column++, 80);
		sheet.setColumnView(column++, 90);
		workbook.write();
		workbook.close();
		log.info("内容写入成功");
		SendMailUtil.sendMessage(mail, inurl, "ccxe");
		ExcelFile ef = new ExcelFile();
		ef.setMail(mail);
		ef.setUrl(inurl);
		insert(ef);
		System.out.println("发送完成");
	}

	/**
	 * 写出转链接的文件
	 * 
	 * @param list
	 * @throws IOException
	 * @throws RowsExceededException
	 * @throws WriteException
	 */
	public static void write(List<Weixin> list) throws Exception {
		File tempFile = new File(url);
		if (!tempFile.exists()) {
			tempFile.createNewFile();
		}
		WritableWorkbook workbook = Workbook.createWorkbook(tempFile);
		WritableSheet sheet = workbook.createSheet("table1", 0);
		// 一些临时变量，用于写到excel中
		Label l = null;
		int seq = 0;
		l = new Label(0, seq, "标题");
		sheet.addCell(l);
		l = new Label(1, seq, "阅读数");
		sheet.addCell(l);
		l = new Label(2, seq, "点赞数");
		sheet.addCell(l);
		l = new Label(3, seq, "时间");
		sheet.addCell(l);
		l = new Label(4, seq, "用户昵称");
		sheet.addCell(l);
		l = new Label(5, seq, "地址");
		sheet.addCell(l);
		l = new Label(6, seq, "简介");
		sheet.addCell(l);
		l = new Label(7, seq, "历史标注");
		sheet.addCell(l);
		l = new Label(8, seq, "长地址");
		sheet.addCell(l);
		l = new Label(9, seq, "mark");
		sheet.addCell(l);
		l = new Label(10, seq, "mark_time");
		sheet.addCell(l);
		l = new Label(11, seq, "markname");
		sheet.addCell(l);
		l = new Label(12, seq, "真实阅读数");
		for (Weixin w : list) {
			seq++;
			l = new Label(0, seq, w.getTitle());
			sheet.addCell(l);
			l = new Label(1, seq, w.getRead());
			sheet.addCell(l);
			l = new Label(2, seq, w.getZan());
			sheet.addCell(l);
			l = new Label(3, seq, w.getTime());
			sheet.addCell(l);
			l = new Label(4, seq, w.getNickname());
			sheet.addCell(l);
			l = new Label(5, seq, w.getGetUrl());
			sheet.addCell(l);
			l = new Label(6, seq, w.getJianjie());
			sheet.addCell(l);
			l = new Label(7, seq, w.getHistory());
			sheet.addCell(l);
			l = new Label(8, seq, w.getLongUrl());
			sheet.addCell(l);
			l = new Label(9, seq, w.getMark());
			sheet.addCell(l);
			l = new Label(10, seq, w.getMark_time());
			sheet.addCell(l);
			l = new Label(11, seq, w.getMarkname());
			sheet.addCell(l);
			l = new Label(12, seq, w.getTrueRead());
		}

		int column = 0;
		sheet.setColumnView(column++, 20);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 30);
		sheet.setColumnView(column++, 80);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 30);
		sheet.setColumnView(column++, 90);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 25);
		sheet.setColumnView(column++, 30);
		workbook.write();
		workbook.close();
		log.info("内容写入成功");

	}

	public static void main(String[] args) {
		try (Socket s = new Socket(host, port);
				PrintWriter pw = new PrintWriter(s.getOutputStream());
				BufferedReader bufferedReader = new BufferedReader(
						new InputStreamReader(s.getInputStream(), "utf-8"));) {
			pw.println("getnum");
			pw.flush();
			String str = bufferedReader.readLine();
			System.out.println("正常运行" + str);
		} catch (Exception e) {
			log.error("错误信息{}", e);
		}
	}

	/**
	 * 将输入流转换成byte[]
	 * 
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	public static byte[] readStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = inStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inStream.close();
		return outSteam.toByteArray();
	}

	/**
	 * socket通信正常执行部分
	 * 
	 * @return
	 */
	public static boolean so() {
		boolean b = true;
		int tip = 0;
		int now = 999;
		try {
			Thread.sleep(1000 * 5);
			while (cut) {// cut=true,插队中
				if (tip == 0) {
					MainController.lists.get(0).setState("暂停中···");
				}
				tip++;
				Thread.sleep(1000);
			}
			if (tip > 0) {
				MainController.lists.get(0).setState("运行中···");
				tip = 0;
			}
			try (Socket s = new Socket(host, port);
					PrintWriter pw = new PrintWriter(s.getOutputStream());
					BufferedReader bufferedReader = new BufferedReader(
							new InputStreamReader(s.getInputStream(), "utf-8"));) {
				pw.println("getnum");
				pw.flush();
				String str = bufferedReader.readLine();
				System.out.println("正常运行" + str);
				Matcher macher = Pattern.compile("num:([0-9]+)\\}").matcher(str);
				if (macher.find()) {
					now = Integer.valueOf(macher.group(1));
					MainController.lists.get(0).setSurplusCount(now);
				}
				if (now == 0) {
					b = false;
				}
				s.close();
			} catch (Exception e) {
				log.error("错误信息{}", e);
			}
		} catch (Exception e) {
			b = false;
			log.error("错误信息{}", e);
		}
		return b;
	}

	/**
	 * 插队部分socket通信执行
	 * 
	 * @return
	 */
	public static boolean cutso() {
		boolean b = true;
		try (Socket s = new Socket(host, port);
				PrintWriter pw = new PrintWriter(s.getOutputStream());
				BufferedReader bufferedReader = new BufferedReader(
						new InputStreamReader(s.getInputStream(), "utf-8"));) {
			pw.println("getnum");
			pw.flush();
			String str = bufferedReader.readLine();
			System.out.println("插队运行" + str);
			if (str.contains("0")) {
				b = false;
			}
		} catch (Exception e) {
			log.error("错误信息{}", e);
		}
		return b;
	}

	/**
	 * 开始插队，socket通信告知
	 * 
	 * @return
	 */
	public static String cutQ() {
		try (Socket s = new Socket(host, port);
				PrintWriter pw = new PrintWriter(s.getOutputStream());
				BufferedReader bufferedReader = new BufferedReader(
						new InputStreamReader(s.getInputStream(), "utf-8"));) {
			pw.println("change");
			pw.flush();
			return bufferedReader.readLine();
		} catch (Exception e) {
			log.error("错误信息{}", e);
		}
		return null;
	}

	/**
	 * 执行插队操作
	 * 
	 * @param id
	 * @return
	 */
	public static String startCut(String id) {
		String msg = cutQ();
		if (msg != null & msg.contains("ok")) {
			for (Excels ex : MainController.lists) {
				System.out.println(id);
				if (ex.getId().equals(id)) {
					cut = true;
					System.out.println("开始插队了");
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					ex.setState("插队中···");
					ex.setStartDate(sdf.format(new Date()));
					MainController.excel = ex;
					Thread t = new Thread() {
						@Override
						public void run() {
							try {
								doChangeUrlWithCut();
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					};
					t.start();
				}
			}
		}
		return msg;
	}

	/**
	 * 运行结束，sokcet告知
	 * 
	 * @return
	 */
	public static String back() {
		try (Socket s = new Socket(host, port);
				PrintWriter pw = new PrintWriter(s.getOutputStream());
				BufferedReader bufferedReader = new BufferedReader(
						new InputStreamReader(s.getInputStream(), "utf-8"));) {
			pw.println("back");
			pw.flush();
			return bufferedReader.readLine();
		} catch (Exception e) {
			log.error("错误信息{}", e);
		}
		return null;
	}

	/**
	 * 插队进行转链接
	 * 
	 * @throws Exception
	 */
	public static void doChangeUrlWithCut() throws Exception {
		System.out.println("插队开始处理");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Excels excel = MainController.excel;
		excel.setStartDate(sdf.format(new Date()));
		List<Weixin> list = ReaderExcel.getExcel(excel.getUrl());
		List<String> urls = new ArrayList<String>();// 写入url
		for (Weixin l : list) {
			if (null != l.getUrl()) {
				if (l.getUrl().startsWith("https://mp.weixin.qq.com/s")
						|| l.getUrl().startsWith("http://mp.weixin.qq.com/s")) {
					urls.add(l.getUrl());
					log.info(l);
				}
			} else {
				continue;
			}
		}
		m.insert(urls);// 存储
		Thread.sleep(1000 * 60);
		while (cutso()) {
			Thread.sleep(1000 * 10);
		}
		Thread.sleep(1000 * 60);
		Map<String, String> map = new HashMap<>();
		for (Map<String, Object> ma : m.find()) {
			if (ma != null && ma.get("url") != null)
				map.put(ma.get("_id").toString(), ma.get("url").toString());
		}
		for (Weixin w : list) {
			if (null != w.getUrl() && w.getUrl().startsWith("https://mp.weixin.qq.com/s")
					|| w.getUrl().startsWith("http://mp.weixin.qq.com/s")) {
				if (map.get(w.getUrl()) != null) {
					w.setGetUrl(map.get(w.getUrl()));
				}
			} else {
				w.setGetUrl(w.getUrl() == null ? "" : w.getUrl());
			}
		}
		write(list, excel.getMail());
		delete(excel.getUrl());
		MainController.lists.remove(excel);
		cut = false;
		back();
		log.info("cut处理完成");
	}

	/**
	 * 转链接主要内容
	 * 
	 * @throws Exception
	 */
	public synchronized static void doChangeUrl() throws Exception {
		runStrat = true;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		while (true) {
			if (MainController.lists.size() > 0) {
				try {
					e = MainController.lists.get(0);
					if (e != null) {
						e.setStartDate(sdf.format(new Date()));
						e.setState("运行中···");
						List<Weixin> list = ReaderExcel.getExcel(e.getUrl());
						List<String> urls = new ArrayList<String>();// 写入url
						for (Weixin l : list) {
							if (null != l.getUrl()) {
								if (l.getUrl().startsWith("https://mp.weixin.qq.com/s?src")
										|| l.getUrl().startsWith("http://mp.weixin.qq.com/s?src")) {
									String demoUrl = l.getUrl().replaceAll("&key=[\\s\\S]+", "");
									l.setUrl(demoUrl);
									urls.add(demoUrl);
									log.info(l);
								}
							} else {
								continue;
							}
						}
						m.insert(urls);// 存储
						Thread.sleep(1000 * 80);// 通信前休眠80s
						while (so()) {
							Thread.sleep(1000 * 10);// 10s交互一次
						}
						Thread.sleep(1000 * 30);
						Map<String, String> map = new HashMap<>();
						for (Map<String, Object> ma : m.find()) {
							try {
								if (ma != null && ma.get("url") != null)
									map.put(ma.get("_id").toString(), ma.get("url").toString());
							} catch (Exception e) {
								log.info("错误信息{}" + e.getMessage());
							}
						}
						for (Weixin w : list) {
							if (w == null) {
								continue;
							}
							try {
								if (null != w.getUrl() && w.getUrl().startsWith("http://mp.weixin.qq.com/s")
										|| w.getUrl().startsWith("https://mp.weixin.qq.com/s")) {
									if (map.get(w.getUrl()) != null) {
										w.setGetUrl(map.get(w.getUrl()));
									}
								} else {
									if (w.getUrl() == null) {
										continue;
									} else
										w.setGetUrl(w.getUrl() == null ? "" : w.getUrl());
								}
							} catch (Exception e) {
								System.out.println(e);
							}
						}
						write(list, e.getMail());
						m.remove();
						MainController.lists.remove(MainController.lists.get(0));
						e = null;
					}
				} catch (NullPointerException e) {
					e.printStackTrace();
					MainController.lists.remove(MainController.lists.get(0));
				} catch (Exception e1) {
					e1.printStackTrace();
					MainController.lists.remove(MainController.lists.get(0));
				}
			} else {
				Thread.sleep(1000 * 60);
			}

		}
	}

	/**
	 * 删除文件
	 * 
	 * @param url
	 *            文件的路径
	 */
	public static void delete(String url) {
		File file = new File(url);
		if (file.isFile()) {
			file.delete();
		}
		log.info("删除完成");
	}

	/**
	 * 转链接结束文件信息存入数据库
	 * 
	 * @param ef
	 */
	public static void insert(ExcelFile ef) {
		m.insertFile(ef);
	}

	/**
	 * 查询所有转链接的文件
	 * 
	 * @return
	 */
	public static List<ExcelFile> findEf() {
		List<ExcelFile> list = m.findFile();
		return list;
	}

	/**
	 * 根据文件id去查询文件
	 * 
	 * @param id
	 * @return
	 */
	public static String findById(String id) {
		return m.findByid(id);
	}

	/**
	 * 读取excel
	 * 
	 * @param url
	 * @return
	 */
	public static List<String> readExcel(String url) {
		InputStream stream = null;
		String str = null;
		List<String> list = new ArrayList<>();
		try {
			stream = new FileInputStream(url);
			Workbook rwb = Workbook.getWorkbook(stream);
			Sheet sheet = rwb.getSheet(0);
			for (int i = 1; i < sheet.getRows(); i++) {
				Cell cell = null;
				for (int j = 0; j < sheet.getColumns(); j++) {
					cell = sheet.getCell(j, i);
					str = cell.getContents();
					if (sheet.getCell(j, 0).getContents().equals("链接")) {
						list.add(str);
					}
				}
			}
			stream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 链接重定向
	 * 
	 * @param url
	 * @return
	 */
	public static String urlRedirect(String url) {
		String result = null;
		try {
			URL ul = new URL(url);
			URLConnection con = ul.openConnection();
			con.setRequestProperty("Host", "mp.weixin.qq.com");
			con.setRequestProperty("User-Agent",
					"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.691.400 QQBrowser/9.0.2524.400");
			result = con.getHeaderField("Location");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		return (result == null || result.equals("")) ? url : result;
	}
}
