package cn.net.cpzslibs.prot;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class Prot01Login extends ProtBase {
	private final short iTaskCode1 = 1;
	/**
	 * 是否成功
	 */
	private short iResult;
	/**
	 * 错误码
	 */
	private short iErrCode;

	/**
	 * 企业Id
	 */
	private int iCompanyId;
	/**
	 * 产品Id
	 */
	private long iProductId;
	/**
	 * 企业工作模式
	 */
	private short iworkStyle;

	/**
	 * imei号
	 */
	private String sInspectorId;

	/**
	 * 当稽查用户登录时，输入的企业id无效，iErrCode=0xFFFE
	 */
	private final int INSPECTION_NOCOMPANY_ID = 0xFFFE;
	/**
	 * 当稽查用户登录时，输入的稽查id无效，iErrCode=0xFFFD
	 */
	private final int INSPECTION_ID = 0xFFFD;
	/**
	 * 当稽查用户登录时，输入的标签id未绑定，iErrCode=0xFFF9
	 */
	private final int INSPECTION_LABLE_ID_UNBIND = 0xFFF9;

	/**
	 * 当消费者用户登录时，输入的标签id未绑定，iErrCode=0xFFFC
	 */
	private final int CONSUMER_LABLE_ID_UNBIND = 0xFFFC;
	/**
	 * 当消费者用户登录时，输入的标签id未能查到产品id，iErrCode=0xFFFB
	 */
	private final int CONSUMER_NO_PRODUCT_ID = 0xFFFB;
	/**
	 * 当消费者用户登录时，输入的标签id未能查到商家id，iErrCode=0xFFFA
	 */
	private final int CONSUMER_NO_COMPANY_ID = 0xFFFA;
	/**
	 * 当消费者用户登录时，无法查到商家对应的工作模式，iErrCode=0xFFF7
	 */
	private final int CONSUMER_NO_WORK_TYPE = 0xFFF7;
	/**
	 * 消费者 登陆时标签的后四位验证码错误，iErrCode=0xFFD6
	 */
	private final int CONSUMER_LABEL_ERR = 0xFFD6;

	/**
	 * 当终端设备用户登录时，输入的设置id未绑定，iErrCode=0xFFF8
	 */
	private final int HANDSET_UN_BIND = 0xFFF8;

	/**
	 * 当监管用户登录时，账号不存在，iErrCode=0xFFF5
	 */
	private final int SUPERVISION_ID_UNEXIST = 0xFFF5;
	/**
	 * 当监管用户登录时，密码错误，iErrCode=0xFFF4
	 */
	private final int SUPERVISION_PWD_ERROR = 0xFFF4;
	/**
	 * 当监管用户登录时，状态无效，iErrCode=0xFFF3;该账号被冻结
	 */
	private final int SUPERVISION_ID_ILLEGAL = 0xFFF3;

	/**
	 * Login的错误信息
	 */
	private String errMsg = "";
	/**
	 * Login的错误码
	 */
	private String errCode = "";

	public Prot01Login(String sInspectorId) {
		this.sInspectorId = sInspectorId;
		
	}

	/**
	 * 1.消费者app登陆
	 * <p>
	 * 2014-12-23下午2:08:15
	 * </p>
	 * 
	 * @param socket
	 * @param dis
	 * @param dos
	 * @param iLabelId
	 *            消费者，输入
	 * @return
	 * @throws IOException
	 */
	public void dealCpzsLogin(Socket socket, DataInputStream dis,
			DataOutputStream dos, long iLabelId) throws IOException {
		short iUserType = 0;// 用户类型: 0-消费者 1-稽查者 2-终端设备
		int iCompanyId = 0; // 企业Id
		long iDeviceId = 0L;// 设备Id必须
		String sAccount = "0";
		String sPassword = "0";
		recProt(socket, dos, dis, iUserType, iLabelId, iCompanyId, iDeviceId,
				sAccount, sPassword);
	}
	
	public void dealCpzsLogin(SocketCreate create, long iLabelId) throws IOException {
		short iUserType = 0;// 用户类型: 0-消费者 1-稽查者 2-终端设备
		int iCompanyId = 0; // 企业Id
		long iDeviceId = 0L;// 设备Id必须
		String sAccount = "0";
		String sPassword = "0";
		recProt(create.getSocket(), create.getDos(), create.getDis(), iUserType, iLabelId, iCompanyId, iDeviceId,
				sAccount, sPassword);
	}

	/**
	 * 1.稽查用户登陆
	 * <p>
	 * 2014-12-23下午2:27:06
	 * </p>
	 * 
	 * @param socket
	 * @param dis
	 * @param dos
	 * @param iCompanyId
	 * @return
	 * @throws IOException
	 */
	public void dealCpzsCheck(Socket socket, DataInputStream dis,
			DataOutputStream dos, int iCompanyId) throws IOException {
		long iLabelId = 0l;
		short iUserType = 1;// 用户类型: 0-消费者 1-稽查者 2-终端设备
		long iDeviceId = 0L;// 设备Id必须
		String sAccount = "0";
		String sPassword = "0";
		recProt(socket, dos, dis, iUserType, iLabelId, iCompanyId, iDeviceId,
				sAccount, sPassword);
	}
	/**
	 * 
	 * @param socket
	 * @param dis
	 * @param dos
	 * @param iCompanyId
	 * @throws IOException
	 */
	public void dealCpzsPhoneCheck(Socket socket, DataInputStream dis,
			DataOutputStream dos, int iCompanyId,boolean isPhone) throws IOException {
		long iLabelId = 0l;
		short iUserType = 1;// 用户类型: 0-消费者 1-稽查者 2-终端设备
		long iDeviceId = 0L;// 设备Id必须
		String sAccount = "0";
		String sPassword = "0";
		recProt(socket, dos, dis, iUserType, iLabelId, iCompanyId, iDeviceId,
				sAccount, sPassword);
	}

	/**
	 * 1.终端机登陆
	 * <p>
	 * 2014-12-23下午2:49:40
	 * </p>
	 * 
	 * @param socket
	 * @param dis
	 * @param dos
	 * @param iDeviceId
	 *            设备id
	 * @return
	 * @throws IOException
	 */
	public void dealCpzsHandset(Socket socket, DataInputStream dis,
			DataOutputStream dos, long iDeviceId) throws IOException {
		short iUserType = 2;// 用户类型: 0-消费者 1-稽查者 2-终端设备
		long iLabelId = 0l;
		int iCompanyId = 0;
		String sAccount = "0";
		String sPassword = "0";
		recProt(socket, dos, dis, iUserType, iLabelId, iCompanyId, iDeviceId,
				sAccount, sPassword);
	}

	/**
	 * 1.登陆协议
	 * <p>
	 * 2014-12-23下午1:59:12
	 * </p>
	 * 
	 * @param socket
	 * @param dos
	 * @param dis
	 * @param iUserType
	 *            用户类型: <br>
	 *            0:消费者<br>
	 *            1:稽查用户 <br>
	 *            2:终端设备 <br>
	 *            3:监管用户<br>
	 * @param iLabelId
	 *            消费用户直接用标签号登录
	 * @param iCompanyId
	 *            企业Id
	 * @param iDeviceId
	 *            设备用户Id
	 * @param sAccount
	 *            监管登录用户
	 * @param sPassword
	 *            监管登录密码
	 * @return
	 * @throws IOException
	 */
	private void recProt(Socket socket, DataOutputStream dos,
			DataInputStream dis, short iUserType, long iLabelId,
			int iCompanyId, long iDeviceId, String sAccount, String sPassword)
			throws IOException {
		if (socket.isConnected()) {
			if (!socket.isOutputShutdown()) {
//				System.out.println("--- iUserType:" + iUserType +"  iLabelId:" + iLabelId +"  iCompanyId:" + iCompanyId +"  iDeviceId:" + iDeviceId +"  sInspectorId:" + sInspectorId+ "  sAccount:" + sAccount +"  sPassword:" + sPassword);
				sendProt(dos, iUserType, iLabelId, iCompanyId, iDeviceId,
						sInspectorId, sAccount, sPassword);
			}
		}
		if (socket.isConnected()) {
			if (!socket.isInputShutdown()) {
				recHeader(dis);
				debugLog(iTaskCode1, toStringRecHeader());
				recLoginDis(dis);
				debugLog(iTaskCode1, toString());
				recCheckCode(dis);
				if (getsResult() == 0) {
					// 成功
					debugLog(iTaskCode1, "读取成功");
				} else {
					if (getsResult() == 1) {

						String ret = "很遗憾，发生异常，异常码为(" + getiErrCode() + ")";
						// 错误
						switch (getiErrCode()) {
						// 输入的设置id未绑定
						case CONSUMER_LABLE_ID_UNBIND:// 当消费者用户登录时，输入的标签id未绑定
						case CONSUMER_NO_PRODUCT_ID:// 输入的标签id未能查到产品id
						case CONSUMER_NO_COMPANY_ID:// 输入的标签id未能查到商家id
						case CONSUMER_NO_WORK_TYPE:// 无法查到商家对应的工作模式
						case CONSUMER_LABEL_ERR:// 标签验证错误
							ret = "您所查询的不是中国追溯的合法凭证(" + getiErrCode() + ")";
							break;
						case HANDSET_UN_BIND:// 当终端设备用户登录时，输入的设置id未绑定
							ret = "手持机id未绑定(" + HANDSET_UN_BIND + ")";
							break;
						case SUPERVISION_ID_UNEXIST:// 当监管用户登录时，账号不存在
							ret = "登录账户不存在(" + SUPERVISION_ID_UNEXIST + ")";
							break;
						case SUPERVISION_PWD_ERROR:// 当监管用户登录时，密码错误
							ret = "密码错误(" + SUPERVISION_PWD_ERROR + ")";
							break;
						case SUPERVISION_ID_ILLEGAL:// 当监管用户登录时，状态无效
							ret = "该账户状态无效(" + SUPERVISION_ID_ILLEGAL + ")";
							break;
						// ---------------------------
						case INSPECTION_NOCOMPANY_ID:// 当稽查用户登录时，输入的企业id无效
							ret = "输入的企业id无效(" + INSPECTION_NOCOMPANY_ID + ")";
							break;
						case INSPECTION_ID:// 当稽查用户登录时，输入的稽查id无效
							ret = "输入的稽查id无效(" + INSPECTION_ID + ")";
							break;
						case INSPECTION_LABLE_ID_UNBIND:// 当稽查用户登录时，输入的标签id未绑定
							ret = "输入的标签id未绑定(" + INSPECTION_LABLE_ID_UNBIND
									+ ")";
							break;
						default:
							break;
						}
						this.errMsg = ret;
						this.errCode = this.iErrCode + "";
						errLog(iTaskCode1, ret);
					} else {
						// 未知错误
						errLog(iTaskCode1, "un err");
					}
				}

			}
		}
	}

	private void recLoginDis(DataInputStream dis) throws IOException {
		this.iResult = dis.readShort();
		this.iErrCode = dis.readShort();
		this.iCompanyId = reciCompanyId(dis);
		this.iProductId = reciProductId(dis);
		this.iworkStyle = dis.readShort();
	}

	/**
	 * 1.登录 发送写一部分
	 * 
	 * @param dos
	 * @param iUserType
	 *            用户类型: 0-消费者 1-稽查者 2-终端设备
	 * @param iLabelId标签号
	 * @param iCompanyId企业Id
	 * @param iDeviceId
	 *            设备Id
	 * @param sUserTag用户唯一标识码
	 *            String 32
	 * @param sAccount
	 *            监管登录用户String() 16
	 * @param sPassword
	 *            监管登录密码long
	 * @throws IOException
	 * 
	 */
	private void sendProt(DataOutputStream dos, short iUserType, long iLabel,
			int iCompanyId, long iDeviceId, String sUserTag, String sAccount,
			String sPassword) throws IOException {

		byte[] sUserTags = sUserTag.getBytes();
		byte[] sendUserTags = new byte[32];
		// 后面补零，服务器遇0认为是空
		System.arraycopy(sUserTags, 0, sendUserTags, 0, sUserTags.length);

		// sAccount 16位 监管登录用户
		byte[] sendAccount = new byte[16];
		System.arraycopy(sAccount.getBytes(), 0, sendAccount, 0,
				sAccount.getBytes().length);

		// sPassword监管登录密码
		byte[] sendPassword = new byte[8];
		System.arraycopy(sPassword.getBytes(), 0, sendPassword, 0,
				sPassword.getBytes().length);

		short bodySize = countBodySize(iUserType, iLabel, iCompanyId,
				iDeviceId, sendUserTags, sendAccount, sendPassword);

		sendHeader(dos, iTaskCode1, bodySize);// 84
		// 用户类型: 0-消费者 1-稽查者 2-终端设备
		dos.writeShort(iUserType);
		// 标签号
		sendiLabel(dos, iLabel);
		// 公司ID
		sendiCompanyId(dos, iCompanyId);
		// 设备id
		dos.writeLong(iDeviceId);
		// 稽查id
		dos.write(sendUserTags);
		// 登陆账户
		dos.write(sendAccount);
		// 登陆账密码
		dos.write(sendPassword);
		sendCheckCode(dos);
	}

	public short getsResult() {
		return iResult;
	}

	public int getiErrCode() {
		return getUnsignedByte(iErrCode);
	}

	/**
	 * 这个强行转成int，为负数 <br/>
	 * 2015-5-14下午6:22:02
	 * @return
	 */
	public short getiShortErrCode() {
		return iErrCode;
	}

	public int getiCompanyId() {
		return iCompanyId;
	}

	public long getiProductId() {
		return iProductId;
	}

	public int getIworkStyle() {
		return iworkStyle;
	}

	public String getsInspectorId() {
		return sInspectorId;
	}

	@Override
	public String toString() {
		return "Prot01Login [sResult=" + iResult + ", iErrCode=" + iErrCode
				+ ", iCompanyId=" + iCompanyId + ", iProductId=" + iProductId
				+ ", iworkStyle=" + iworkStyle + ", sInspectorId="
				+ sInspectorId + "]";
	}

	/**
	 * 错误信息 <br/>
	 * 2015-4-3下午3:56:41
	 * 
	 * @return
	 */
	public String getErrMsg() {
		return errMsg;
	}

	/**
	 * 错误码 <br/>
	 * 2015-4-3下午3:58:26
	 * 
	 * @return
	 */
	public String getErrCode() {
		return errCode;
	}

}
