package cn.net.cpzslibs.prot;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.BindException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

/**
 * 
 * @author zwj<br/>
 *         2015年4月26日 09:31:56
 * @version 1.1
 */
public class SocketCreate {

	private Socket socket;
	private DataInputStream dis;
	private DataOutputStream dos;
	private boolean result = false;// 登录是否成功
	private int iWorkStyle = 0;// 工作模式
	private int iCompanyId = 0;// 公司ID
	private long iProductId = 0;// 产品ID

	private final short userTypeJustCreateScoket = 100;// 只是创建socket
	private final short userTypeCons = 0;// 消费者
	private final short userTypeCheck = 1;// 稽查
	private final short userTypeHandset = 2;// 终端
	private final short userTypeSuper = 3;// 管理，未使用
	private long iDeviceId;
	private long iLabel;// 登录追溯码
	private int iTaskIndex = 0;// 协议的序列号

	private String ip;// ip地址
	private int port;// 端口号
//	private int iConnTimeout = 1000 * 180;// 链接超时   1000 * 30
//	private int iReadTimeout = 1000 * 180;// 读取数据超时   1000 * 30
	
	private int iConnTimeout = 1000 * 180; // 链接超时   1000 * 30
	private int iReadTimeout = 1000 * 180; // 读取数据超时   1000 * 30
	private String sInspectorId;//imei号登录
	/**
	 * Login的错误信息
	 */
	private String errMsg = "";
	/**
	 * Login的错误码，正数
	 */
	private int iErrCode;
	/**
	 * Login的负数错误码
	 */
	private int iShortErrCode;

	/**
	 * 
	 * @param ip
	 *            ip地址
	 * @param port
	 *            端口
	 * @param iConnTimeout
	 *            链接超时,默认30s
	 * @param iReadTimeout
	 *            读超时时间,默认30s
	 * @param sInspectorId
	 *            设备号
	 */
	public SocketCreate(String ip, int port, String sInspectorId) {
		this.ip = ip;
		this.port = port;
		this.sInspectorId = (sInspectorId == null || "".equals(sInspectorId)) ? "0" : sInspectorId;
	}
	/**
	 * @param ip:ip地址
	 * @param port:端口号
	 */
	public SocketCreate(String ip, int port) {
		this.ip = ip;
		this.port = port;
	}

	/**
	 * 
	 * @param ip
	 *            ip地址
	 * @param port
	 *            端口
	 * @param iConnTimeout
	 *            链接超时
	 * @param iReadTimeout
	 *            读超时时间
	 * @param sInspectorId
	 *            设备号
	 */
	public SocketCreate(String ip, int port, int iConnTimeout, int iReadTimeout, String sInspectorId) {
		this.ip = ip;
		this.port = port;
		this.iConnTimeout = iConnTimeout;
		this.iReadTimeout = iReadTimeout;
		this.sInspectorId = (sInspectorId == null || "".equals(sInspectorId)) ? "0" : sInspectorId;
	}

	/**
	 * 消费者app登陆
	 * <p>
	 * 2014-12-24下午4:41:22
	 * </p>
	 * 
	 * @param context
	 * @param iLabel
	 * @param mHandler
	 * @param ip
	 * @param port
	 * @param timeOut
	 * @throws IOException
	 */
	public void createLoginCpzs(long iLabel)
			throws BindException, ConnectException, SocketTimeoutException, UnknownHostException, IOException {
		// 消费者app登陆
		result = createServeConnect(iLabel, userTypeCons);
	}

	/**
	 * 稽查app登陆
	 * <p>
	 * 2014-12-30下午1:23:31
	 * </p>
	 * 
	 * @param ip
	 * @param port
	 * @param timeOut
	 * @param iCompanyId
	 * @throws IOException
	 */
	public void createLoginCpzsCheck(int iCompanyId)
			throws BindException, ConnectException, SocketTimeoutException, UnknownHostException, IOException {
		this.iCompanyId = iCompanyId;
//		this.sAccount = (sAccount == null || "".equals(sAccount))?"0":sAccount;
		result = createServeConnect(0L, userTypeCheck);
	}

	/**
	 * 终端app登陆
	 * <p>
	 * 2014-12-30下午1:22:53
	 * </p>
	 * 
	 * @param ip
	 * @param port
	 * @param timeOut
	 * @param iDeviceId
	 * @throws IOException
	 */
	public void createLoginCpzsHandset(long iDeviceId)
			throws BindException, ConnectException, SocketTimeoutException, UnknownHostException, IOException {
		this.iDeviceId = iDeviceId;
		result = createServeConnect(0L, userTypeHandset);
	}

	/**
	 * 只是创建socket的链接，无login <br/>
	 * 2015-9-9上午11:02:59
	 * 
	 * @param iDeviceId
	 * @throws BindException
	 * @throws ConnectException
	 * @throws SocketTimeoutException
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public void createJustCreateSocket()
			throws BindException, ConnectException, SocketTimeoutException, UnknownHostException, IOException {
		result = createServeConnect(0L, userTypeJustCreateScoket);
	}

	/**
	 * 2014-5-23下午1:13:57
	 * 
	 * @param context
	 * @param laelId
	 * @return 返回true，Login成功；false:无网络，login失败,
	 * @throws BindException
	 * @throws SocketTimeoutException
	 * @throws ConnectException
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	private boolean createServeConnect(long labelId, int iUserType)
			throws BindException, ConnectException, SocketTimeoutException, UnknownHostException, IOException {
		iLabel = labelId;
		boolean isJustCreateSocket = false;
		if (!createSocketConnect(ip, port, iConnTimeout, iReadTimeout)) {
			// 错误直接返回
			return false;
		}

		Prot01Login prot01Login = new Prot01Login(sInspectorId);
		switch (iUserType) {
		case userTypeCons:
			// 消费者app
			prot01Login.dealCpzsLogin(socket, dis, dos, labelId);
			break;
		case userTypeCheck:
			// 稽查app
			prot01Login.dealCpzsCheck(socket, dis, dos, iCompanyId);
			break;
		case userTypeHandset:
			// 终端设备 app
			prot01Login.dealCpzsHandset(socket, dis, dos, iDeviceId);
			break;
		case userTypeSuper:
			// 监管用户 app--暂时用不到
			break;
		case userTypeJustCreateScoket:
			isJustCreateSocket = true;
			break;

		default:
			break;
		}
		if (isJustCreateSocket) {
			result = true;
			return result;
		}

		if (prot01Login.getiErrCode() == 0) {
			result = true;
			iWorkStyle = prot01Login.getIworkStyle();
			iCompanyId = prot01Login.getiCompanyId();
			iProductId = prot01Login.getiProductId();
			iTaskIndex = prot01Login.getiSendTaskIndex();
			return true;
		} else {
			errMsg = prot01Login.getErrMsg();
			iErrCode = prot01Login.getiErrCode();
			iShortErrCode = prot01Login.getiShortErrCode();
			return false;
		}
	}

	/**
	 * 创建socket的连接
	 * 
	 * @author zwj<br/>
	 *         2015-4-26 上午9:10:05<br/>
	 * @param ip
	 * @param port
	 * @param iReadTimeout
	 * @return
	 * @throws BindException
	 * @throws ConnectException
	 * @throws UnknownHostException
	 * @throws SocketTimeoutException
	 * @throws IOException
	 */
	private boolean createSocketConnect(String ip, int port, int iConnTimeout, int iReadTimeout)
			throws BindException, ConnectException, UnknownHostException, SocketTimeoutException, IOException {
		SocketAddress socketAddress = new InetSocketAddress(ip, port);
		socket = new Socket();
		socket.connect(socketAddress, iConnTimeout);
		socket.setSoTimeout(iReadTimeout);
		dis = new DataInputStream(socket.getInputStream());
		dos = new DataOutputStream(socket.getOutputStream());
		if (null != socket && socket.isConnected() && !socket.isOutputShutdown() && !socket.isInputShutdown()) {
			return true;
		}
		return false;
	}

	public Socket getSocket() {
		return socket;
	}

	public DataInputStream getDis() {
		return dis;
	}

	public DataOutputStream getDos() {
		return dos;
	}

	public boolean isResult() {
		return result;
	}

	public int getiWorkStyle() {
		return iWorkStyle;
	}

	public int getiCompanyId() {
		return iCompanyId;
	}

	public long getiProductId() {
		return iProductId;
	}

	public long getiLabel() {
		return iLabel;
	}

	/**
	 * imei号 <br/>
	 * 2015-5-11下午2:45:28
	 * 
	 * @return
	 */
	public String getsInspectorId() {
		return sInspectorId;
	}

	public int getiTaskIndex() {
		return ++iTaskIndex;
	}

	/**
	 * 设备id，手持机id <br/>
	 * 2015-5-11下午2:44:59
	 * 
	 * @return
	 */
	public long getiDeviceId() {
		return iDeviceId;
	}

	/**
	 * 登录错误信息，描述语句 <br/>
	 * 2015-5-11下午2:44:33
	 * 
	 * @return
	 */
	public String getErrMsg() {
		return errMsg;
	}

	/**
	 * 登录错误码 ，正数<br/>
	 * 2015-5-11下午3:25:14
	 * 
	 * @return
	 */
	public int getiErrCode() {
		return iErrCode;
	}

	/**
	 * 登录错误码 ,负数<br/>
	 * 2015-5-11下午3:25:14
	 * 
	 * @return
	 */
	public int getiShortErrCode() {
		return iShortErrCode;
	}
}
