package com.xt.hb.data.camera.svcimpl;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ctc.wstx.util.StringUtil;
import com.xt.hb.data.camera.mapper.CameraMapper;
import com.xt.hb.data.camera.model.CameraInfo;
import com.xt.hb.data.camera.model.CameraUserInfo;
import com.xt.hb.data.service.FetchService;
import com.xt.hb.data.system.GlobalData;
import com.yuanxd.tools.utils.CollectionUtils;

/**
 * @author zhaoyong
 */
@Service
public class CameraService implements FetchService {

	private final static Logger logger = LoggerFactory.getLogger(CameraService.class);

	@Autowired
	private CameraMapper cameraMapper;

	@SuppressWarnings("unchecked")
	public List<CameraInfo> getAllCameraInfoList() {
		List<CameraInfo> cameraInfos = null;

		CameraUserInfo userInfo = this.userLogin();
		if (null != userInfo && null != userInfo.getSessionId()
				&& !StringUtil.isAllWhitespace(userInfo.getSessionId())) {
			StringBuffer sb = new StringBuffer();
			sb.append(
					"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.cms.hikvision.com\">")
					.append("<soapenv:Header/>").append("<soapenv:Body>").append("<web:getAllCameraInfoForList>")
					.append("<web:sessionId>").append(userInfo.getSessionId()).append("</web:sessionId>")
					.append("</web:getAllCameraInfoForList>").append("</soapenv:Body>").append("</soapenv:Envelope>");
			// 请求
			String reqContent = sb.toString();
			try {
				InputStream in = this.callWebService(GlobalData.HIKVISION_CMS_WSDL, reqContent);
				if (null != in) {
					// 解析数据
					SAXReader reader = new SAXReader();
					Document doc = reader.read(in);
					HashMap<String, String> xmlMap = new HashMap<String, String>();
					xmlMap.put("ax236", "http://bo.webservice.cms.hikvision.com/xsd");

					XPath cameraInfoXpath = doc.createXPath("//ax236:cameraInfoDTOArray");
					cameraInfoXpath.setNamespaceURIs(xmlMap);
					List<Node> cameraInfoNodes = cameraInfoXpath.selectNodes(doc);
					if (null != cameraInfoNodes && !cameraInfoNodes.isEmpty()) {
						cameraInfos = new ArrayList<CameraInfo>();
						for (Node cameraInfoNode : cameraInfoNodes) {
							CameraInfo cameraInfo = this.parseCameraInfo(cameraInfoNode);
							if (null == cameraInfo) {
								continue;
							}
							cameraInfos.add(cameraInfo);
						}

						if (!CollectionUtils.isEmpty(cameraInfos)) {
							for (CameraInfo camera : cameraInfos) {
								this.cameraMapper.persistCamera(camera);
							}
						}
					}
				}
			} catch (Exception e) {
				logger.error("Invoking Hikvision interface {} error.", "getAllCameraInfoForList", e);
			}
		}
		return cameraInfos;
	}

	/**
	 * 解析监控点数据
	 * 
	 * @param cameraInfoNode
	 * @return
	 */
	private CameraInfo parseCameraInfo(Node cameraInfoNode) {
		CameraInfo cameraInfo = null;
		if (null != cameraInfoNode) {
			Node cameraId = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:cameraId");
			if (null != cameraId) {
				cameraInfo = new CameraInfo();
				cameraInfo.setCameraId(cameraId.getStringValue());
				Node indexCode = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:indexCode");
				cameraInfo.setIndexCode(null != indexCode ? indexCode.getStringValue() : "");
				Node name = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:name");
				cameraInfo.setName(null != name ? name.getStringValue() : "");
				Node regionId = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:regionId");
				cameraInfo.setRegionId(null != regionId ? regionId.getStringValue() : "");
				Node cameraType = cameraInfoNode
						.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:cameraType");
				cameraInfo.setCameraType(null != cameraType ? cameraType.getStringValue() : "");
				Node streamType = cameraInfoNode
						.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:streamType");
				cameraInfo.setStreamType(null != streamType ? streamType.getStringValue() : "");
				Node pixel = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:pixel");
				cameraInfo.setPixel(null != pixel ? pixel.getStringValue() : "");
				Node ptzType = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:ptzType");
				cameraInfo.setPtzType(null != ptzType ? ptzType.getStringValue() : "");
				Node sound = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:sound");
				cameraInfo.setSound(null != sound ? sound.getStringValue() : "");
				Node longitude = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:longitude");
				cameraInfo.setLongitude(null != longitude ? longitude.getStringValue() : "");
				Node latitude = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:latitude");
				cameraInfo.setLatitude(null != latitude ? latitude.getStringValue() : "");
				Node curState = cameraInfoNode.selectSingleNode(cameraInfoNode.getUniquePath() + "//ax236:curState");
				cameraInfo.setCurState(null != curState ? curState.getStringValue() : "1");
				;
			}
		}
		return cameraInfo;
	}

	public List<CameraInfo> getCameraInfoListByRegionId(String regionId) {
		List<CameraInfo> cameras = new ArrayList<CameraInfo>();
		if (null != regionId && !StringUtil.isAllWhitespace(regionId)) {
			// 从数据库获取数据
			cameras = cameraMapper.listCamerasByRegionId(regionId);
		}
		return cameras;
	}

	private CameraUserInfo userLogin() {
		CameraUserInfo userInfo = new CameraUserInfo();
		// 构造登录用户名,密码
		userInfo.setUsername(GlobalData.HIKVISION_PLATFORM_USER);
		userInfo.setPassword(GlobalData.HIKVISION_PLATFORM_PWD);

		StringBuffer sb = new StringBuffer();
		sb.append(
				"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.cms.hikvision.com\">")
				.append("<soapenv:Header/>").append("<soapenv:Body>").append("<web:userLogin>").append("<web:userName>")
				.append(userInfo.getUsername()).append("</web:userName>").append("<web:pwd>")
				.append(userInfo.getPassword()).append("</web:pwd>").append(" <web:clientIp>").append("")
				.append("</web:clientIp>").append("<web:clientPort>80</web:clientPort>").append("<web:cmsUrl>")
				.append(GlobalData.HIKVISION_PLATFORM_URL).append("</web:cmsUrl>").append("</web:userLogin>")
				.append("</soapenv:Body>").append("</soapenv:Envelope>");

		// 请求
		String reqContent = sb.toString();
		try {
			InputStream in = this.callWebService(GlobalData.HIKVISION_CMS_WSDL, reqContent);
			if (null != in) {
				// 解析数据
				SAXReader reader = new SAXReader();
				Document doc = reader.read(in);

				HashMap<String, String> xmlMap = new HashMap<String, String>();
				xmlMap.put("ax236", "http://bo.webservice.cms.hikvision.com/xsd");

				XPath sessionIdXpath = doc.createXPath("//ax236:sessionId");
				sessionIdXpath.setNamespaceURIs(xmlMap);
				Node sessionIdNode = sessionIdXpath.selectSingleNode(doc);
				if (null != sessionIdNode) {
					// 设置sessionId
					userInfo.setSessionId(sessionIdNode.getStringValue());
				}
			}
		} catch (Exception e) {
			logger.error("Invoking Hikvision interface {} error.", "userLogin", e);
		}

		logger.debug("Invoking Hikvision interface {} successful, userInfo[{}].", "userLogin", userInfo);
		return userInfo;
	}

	private InputStream callWebService(String reqUrl, String reqContent) throws Exception {
		System.setProperty("sun.net.client.defaultConnectTimeout", "20000");
		System.setProperty("sun.net.client.defaultReadTimeout", "20000");
		// URL连接
		URL url = new URL(reqUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Content-Length", String.valueOf(reqContent.getBytes().length));
		conn.setRequestProperty("Content-Type", "text/xml; charset=GBK");
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setConnectTimeout(20000);
		// 请求输入内容
		OutputStream output = conn.getOutputStream();
		output.write(reqContent.getBytes());
		output.flush();
		output.close();
		// 请求返回内容
		return conn.getInputStream();
	}

	@Override
	public int doFetch() {
		List<CameraInfo> cameras = getAllCameraInfoList();
		return cameras.size();
	}

	/**
	 * 从数据库中获取所有摄像头信息
	 * @return
	 */
	public List<CameraInfo> getAllCameraList() {
		List<CameraInfo> cameras = new ArrayList<CameraInfo>();
		cameras = cameraMapper.getAllCameraList();
		return cameras;
	}

	@Override
	public String getName() {
		return "摄像头列表";
	}

	@Override
	public String message() {
		return "";
	}

}