package com.jiayue.ipfcst.client.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jiayue.ipfcst.client.domain.entity.ClientConfig;
import com.jiayue.ipfcst.client.domain.entity.ClientResponse;
import com.jiayue.ipfcst.client.domain.entity.FileCreateLog;
import com.jiayue.ipfcst.client.utils.ClientFileUtils;
import com.jiayue.ipfcst.client.utils.Constant;
import com.jiayue.ipfcst.client.utils.Md5Util;
import com.jiayue.ipfcst.client.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * DownLoadController
 *
 * 外网部署client端手动点击下载执行下载短期和nwp文件
 *
 * 先获取FileCreateLog列表，根据FileCreateLog信息通过http遍历请求下载文件
 *
 * @author bizy
 * @version 1.0
 * @since 2019/4/9 13:36
 */
@Slf4j
@RestController
public class HomeController {

	/**
	 * 手动下载当天文件
	 * @param request
	 * @return
	 */
	@RequestMapping("/downloadfile")
	public JSONObject download(HttpServletRequest request) {
/*


		String stationCode = request.getParameter("localstationCode");
		String downFilePath = request.getParameter("localdownFilePath");
		log.info("手动下载RB文件开始，时间：" + TimeUtils.getStringDate());
		StringBuffer filePathList = new StringBuffer();
		int status = 500;
		String message = "500";

		String requestUrl = Constant.cacheClientConfig.getCloudAddr();
		log.info("V3云预测文件下载地址："+requestUrl);
		Map postParms = new HashMap<>(2);
		postParms.put("stationCode",stationCode);
		postParms.put("sign", Md5Util.makeMd5(stationCode));
		String body = HttpUtil.post(requestUrl+"/getCurentDayAllFiles",postParms,5000);
		log.info("请求V3云预测文件下载获得响应：{}",body);
		JSONObject json = JSONUtil.parseObj(body);
		String code = json.get("code").toString();
		String data = json.get("data").toString();
		// 下载失败列表
		Map<String,String> downFileInfoMap = new HashMap<>();

		if (code.equals("0") && data.length() > 0) {
			JSONArray array = JSONUtil.parseArray(data);
			List<FileCreateLog> list = array.toList(FileCreateLog.class);
			// 从何处下载的文件
			String flag = "minio";

			// 从minio下载
			downFileInfoMap = getFileFromMinio(list, downFilePath, filePathList, downFileInfoMap);

			// 从minio下载失败，从云端下载补下载
			if (downFileInfoMap.size()>0) {

				log.info("从minio下载失败，从云端下载");
				// 从云平台补下载 从minio下载失败的文件
				for(Map.Entry<String,String> map: downFileInfoMap.entrySet()){
					String url = requestUrl + "/downloadFileById?id=" + map.getKey() + "&sign=" + Md5Util.makeMd5(map.getKey());
					try {
						HttpUtil.downloadFile(url, new File(downFilePath + File.separatorChar + map.getValue()), 60000);
						filePathList.append(downFilePath + File.separatorChar + map.getValue() + " 该文件是从云端补下载<br>");
						// 移除下载成功的文件
						downFileInfoMap.remove(map.getKey());
					} catch (Exception e) {
						log.error("当前文件{}下载失败：{}", map.getValue(),e);
						downFileInfoMap.put(map.getValue(),e.toString());
					}
				}

				flag = "minio 和 云平台";
			}
			if (list.size() > 0) {
				int size = list.size() - downFileInfoMap.size();
				message = "下载成功！ 应下载："+list.size() +" ，实际下载：" + size + "，当前文件是从" + flag + "下载";
			} else {
				message = "下载完成！,云预测未生成该场站今日的文件，请联系运维人员手动生成。";
			}
			if(downFileInfoMap.size() > 0){
				for(Map.Entry<String,String> map: downFileInfoMap.entrySet()){
					filePathList.append(map.getKey()+"下载失败："+map.getValue());
				}
			}
			status = 200;
		} else {
			message = "请求云预测获取文件信息错误,请求地址：" + requestUrl + ";响应信息：" + json.toString();
			log.warn("查询 FileCreateLog 失败，查询返回：{},{}", code, data);
		}
		JSONObject result = new JSONObject();
		result.put("status",status);
		result.put("message",message);
		result.put("filepathlist",filePathList.toString());

		return result;


 */

		String stationCode = request.getParameter("localstationCode");
		String downFilePath = request.getParameter("localdownFilePath");
		log.info("手动下载RB文件开始，时间：" + TimeUtils.getStringDate());
		StringBuffer filePathList = new StringBuffer();
		int status = 500;
		String message = "500";

		StringBuffer fileName = new StringBuffer();
		String requestUrl = Constant.cacheClientConfig.getCloudAddr();
		log.info("V3云预测文件下载地址："+requestUrl);

		Map<String, Object> stringObjectMap = downFilePathByStationCode(stationCode, requestUrl, downFilePath, filePathList, message, status);
		if("J00192".equals(stationCode)){
			log.info("当前场站是龙阜风电场，需要再下载一期，二期对应的单独气象文件");
			downFilePathByStationCode("J00389",requestUrl,downFilePath,filePathList,message,status);
			downFilePathByStationCode("J00390",requestUrl,downFilePath,filePathList,message,status);
		}

		status = (int) stringObjectMap.get("status");
		message = stringObjectMap.get("message").toString();
		JSONObject result = new JSONObject();
		result.put("status",status);
		result.put("message",message);
		result.put("filepathlist",filePathList.toString());

		return result;
	}

	/**
	 * 下载场站编码对应的预测文件
	 * @param stationCode
	 * @param requestUrl
	 * @param downFilePath
	 * @param filePathList
	 * @param message
	 * @param status
	 */
	private Map<String,Object> downFilePathByStationCode(String stationCode,String requestUrl,String downFilePath,StringBuffer filePathList,String message,Integer status) {
		Map<String,Object> result = new HashMap();
		Map postParms = new HashMap<>(2);
		postParms.put("stationCode",stationCode);
		postParms.put("sign", Md5Util.makeMd5(stationCode));
		String body = HttpUtil.post(requestUrl+"/getCurentDayAllFiles",postParms,5000);
		log.info("请求V3云预测文件下载获得响应：{}",body);
		JSONObject json = JSONUtil.parseObj(body);
		String code = json.get("code").toString();
		String data = json.get("data").toString();
		if (code.equals("0") && data.length() > 0) {
			try {
				JSONArray array = JSONUtil.parseArray(data);
				List<FileCreateLog> list = array.toList(FileCreateLog.class);
				for (FileCreateLog fileCreateLog : list) {
					log.info("下载文件：{}",fileCreateLog.toString());
					String url = requestUrl + "/downloadFileById?id=" + fileCreateLog.getId()+"&sign="+ Md5Util.makeMd5(fileCreateLog.getId());
					HttpUtil.downloadFile(url, new File(downFilePath + File.separatorChar + fileCreateLog.getFileName()),60000);
					filePathList.append(downFilePath + File.separatorChar + fileCreateLog.getFileName()+"<br>");
				}
				log.info("所有文件下载成功，共下载 {} 个文件。",list.size());
				if(list.size()>0){
					message = "下载成功！,共下载"+list.size()+"个文件";
				}else{
					message = "下载完成！,云预测未生成该场站今日的文件，请联系运维人员手动生成。";
				}
				status = 200;
			} catch (Exception e) {
				log.error("文件下载失败", e);
			}
		}else {
			message = "请求云预测获取文件信息错误,请求地址："+requestUrl+";响应信息："+json.toString();
			log.warn("查询 FileCreateLog 失败，查询返回：{},{}",code,data);
		}
		result.put("status", status);
		result.put("message",message);
		return result;
	}

	public Map<String,String> getFileFromMinio(List<FileCreateLog> list,String downFilePath,StringBuffer filePathList,Map<String,String> downFileInfoMap){

		for (FileCreateLog fileCreateLog : list) {
			log.info("从minio下载文件：{}", fileCreateLog.toString());
			try {
				// 从minio下载
				HttpUtil.downloadFile(fileCreateLog.getFileDownloadUrl(), new File(downFilePath + File.separatorChar
						+ fileCreateLog.getFileName()), 20000);
				filePathList.append(downFilePath + File.separatorChar + fileCreateLog.getFileName() + "<br>");
			} catch (Exception e) {
				log.error("从minio下载当前文件失败：{}，文件名：{}", e,fileCreateLog.getFileName());
				downFileInfoMap.put(fileCreateLog.getId(),fileCreateLog.getFileName());
			}
		}
		if(downFileInfoMap.size() > 0){
			downFileInfoMap.forEach((k,v) -> {
				log.error("{}文件下载失败，稍后从云上下载",v);
			});
		}else {
			log.info("从minio所有文件下载成功，共下载 {} 个文件。", list.size());
		}

		return downFileInfoMap;
	}



	@RequestMapping("/restExternal")
	public JSONObject restExternal() {
		JSONObject result = new JSONObject();
		try {
			Runtime.getRuntime().exec("service external restart");
			result.put("status",200);
			result.put("message","重启成功");
		}catch (Exception e){
			result.put("status",500);
			result.put("message","重启错误："+e.getLocalizedMessage());
		}
		return result;
	}

	@RequestMapping("/restClient")
	public JSONObject restClient() {
		JSONObject result = new JSONObject();
		try {
			Runtime.getRuntime().exec("service client restart");
			result.put("status",200);
			result.put("message","重启成功");
		}catch (Exception e){
			result.put("status",500);
			result.put("message","重启错误："+e.getLocalizedMessage());
		}
		return result;
	}
	/**
	 * 获取本地参数配置信息
	 * @return
	 */
	@RequestMapping("/getClientConfig")
	public ClientConfig getClientConfig() {
		return Constant.cacheClientConfig;
	}

	/**
	 * 保存参数到本地文件并上送云控制
	 * @param clientConfigTemp
	 *
	 * @return
	 */

	@RequestMapping("/saveClientConfig")
	public JSONObject saveClientConfig(ClientConfig clientConfigTemp) {
		//同步更新场站配置文件的信息
		ClientConfig clientConfig = Constant.cacheClientConfig;
		clientConfig.setFxglType(clientConfigTemp.getFxglType().trim());
		clientConfig.setDownLoadProtocol(clientConfigTemp.getDownLoadProtocol().trim());
		clientConfig.setFxglPath(clientConfigTemp.getFxglPath().trim());
		clientConfig.setZxglPath(clientConfigTemp.getZxglPath().trim());
		clientConfig.setRenameFile(clientConfigTemp.getRenameFile().trim());
		//先保存到本地文件
		ClientFileUtils.createJsonFile(JSONUtil.toJsonStr(clientConfig),"./clientConfig.properties");
		Constant.cacheClientConfig = clientConfig;
		int status = 500;
		String message = "保存成功";

		try {
			Map postParms = new HashMap<>(2);
			postParms.put("stationCode",Constant.cacheClientConfig.getStationCode());
			postParms.put("fxglType",clientConfigTemp.getFxglType().trim());
			postParms.put("downLoadProtocol",clientConfigTemp.getDownLoadProtocol().trim());
			postParms.put("fxglPath",clientConfigTemp.getFxglPath().trim());
			postParms.put("zxglPath",clientConfigTemp.getZxglPath().trim());
			postParms.put("renameFile",clientConfigTemp.getRenameFile().trim());
			postParms.put("sign", Md5Util.makeMd5(Constant.cacheClientConfig.getStationCode()));
			String	resp = HttpUtil.post(clientConfig.getCloudAddr() + "saveConfigInfo",postParms,5000);
			ClientResponse response = JSONUtil.toBean(resp, ClientResponse.class);
			if(0 == response.getCode()){
				status = 200;
				message = "保存并成功推送到云预测平台";
			}else{
				message = response.getMsg();
			}
		}catch (Exception e){
			message = "保存本地成功但推送云端失败："+ e.getLocalizedMessage();
		}

		JSONObject result = new JSONObject();
		result.put("status",status);
		result.put("message",message);
		return result;
	}

	/**
	 * 保存系统默认配置到本地文件
	 * @param request
	 * @return
	 */
	@RequestMapping("/saveDefaultClientConfig")
	public JSONObject saveDefaultClientConfig(HttpServletRequest request) {
		log.info("更新系统参数并同步到配置文件中");
		String stationCode = request.getParameter("defaultStationCode").trim();
		String defaultCloudAddr = request.getParameter("defaultCloudAddr").trim();
		String dqAndNwpFileTask = request.getParameter("dqAndNwpFileTask").trim();
		String fxglTask = request.getParameter("fxglTask").trim();
		String zxglTask = request.getParameter("zxglTask").trim();
		int status = 500;
		String message = "保存配置信息失败";
		try {
			Map defaultConfig = new HashMap();
			defaultConfig.put("stationCode",stationCode);
			defaultConfig.put("cloudAddr",defaultCloudAddr);
			defaultConfig.put("dqAndNwpFileTask",dqAndNwpFileTask);
			defaultConfig.put("fxglTask",fxglTask);
			defaultConfig.put("zxglTask",zxglTask);
			ClientFileUtils.createJsonFile(JSONUtil.toJsonStr(defaultConfig),"./default.properties");
			//同步更新场站配置文件的信息
			ClientConfig clientConfig = Constant.cacheClientConfig;
			clientConfig.setStationCode(stationCode);
			clientConfig.setCloudAddr(defaultCloudAddr);
			clientConfig.setDqAndNwpFileTask(dqAndNwpFileTask);
			clientConfig.setFxglTask(fxglTask);
			clientConfig.setZxglTask(zxglTask);
			ClientFileUtils.createJsonFile(JSONUtil.toJsonStr(clientConfig),"./clientConfig.properties");
			Constant.cacheClientConfig = clientConfig;
			status = 200;
			message = "保存成功系统配置成功";
		}catch (Exception e){
			message = e.getLocalizedMessage();
		}

		JSONObject result = new JSONObject();
		result.put("status",status);
		result.put("message",message);
		return result;
	}

	/**
	 * 与云预测网络联通性测试
	 * @return
	 */
	@RequestMapping("/testNet")
	public JSONObject testNet() {
		int status = 500;
		String message = "无法访问V3云预测";
		try {
			//同步场站配置文件的信息
			ClientConfig clientConfig = Constant.cacheClientConfig;
			if(null != clientConfig){
				Map postParms = new HashMap<>(2);
				postParms.put("stationCode",Constant.cacheClientConfig.getStationCode());
				postParms.put("sign", Md5Util.makeMd5(Constant.cacheClientConfig.getStationCode()));
				String body = HttpUtil.get(clientConfig.getCloudAddr() + "/getClientInfo/" ,postParms,5000);
				JSONObject json = JSONUtil.parseObj(body);
				String code = json.get("code").toString();
				String data = json.get("data").toString();
				if (code.equals("0") && data.length() > 0) {
					status = 200;
					message = "与云预测网络联通正常";
				}
			}
		}catch (Exception e){
			log.error("网络测试故障：{}",e);
		}

		JSONObject result = new JSONObject();
		result.put("status",status);
		result.put("message",message);
		return result;
	}


}
