package cn.net.cpzslibs.prot.handset;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import cn.net.cpzslibs.prot.ProtBase;
import cn.net.cpzslibs.prot.SocketCreate;

/**
 * 酒-->生产功能包含:激活，标签操作，设置销售区域
 * 
 * @author zwj
 * 
 *         2015-7-30
 */
public class Prot27Production extends ProtBase {
	private final short iTaskCode27 = 27;// 无序上传
	private final int iMaxSendDisorderSize = 1000;// 无序最大一次上传

	private CallBack iBack;

	public interface CallBack {
		/**
		 * 
		 * <br/>
		 * 2015-5-5上午10:46:40
		 * 
		 * @param bool
		 *            是否成功
		 * @param labels
		 *            label数组
		 * @param errRet
		 *            错误信息提示(异常(错误码))
		 * @param iFailedNum
		 *            >0表示已经有标签被操作，=0正常
		 */
		public void updateData(boolean bool, List<Long> labels, String errRet,
                               int iErrCode, int iFailedNum);
	}

	/*----------------------------------------------------------*/
	/**
	 * 包追溯码
	 */
	public final String kPackageId = "PackageId";
	/**
	 * 产品id
	 */
	public final String kProdcutId = "ProdcutId";
	/**
	 * 产品日期
	 */
	public final String kProduceDate = "ProduceDate";
	/**
	 * 产品批号
	 */
	public final String kBatchNumber = "BatchNumber";
	/**
	 * 操作类型
	 */
	public final String kOptAction = "OptAction";

	/**
	 * 操作说明
	 */
	public final String kOptMemoStr = "instr";
	/**
	 * 销售地区
	 */
	public final String kAreaCode = "AreaCode";

	/*----------------------------------------------------------*/

	/**
	 * 27号协议-->酒生产功能包含:激活，标签操作，设置销售区域 <br/>
	 * 2015-7-30下午3:51:45
	 * 
	 * @param create
	 * @param listSrc
	 * @param back
	 * @throws IOException
	 */
	public void dealProt(SocketCreate create, Map<String, String> packageInfo,
                         List<Long> listSrc, CallBack back)
			throws IOException {
		this.iBack = back;
		int listSrcSize = listSrc.size();
		int subs = listSrcSize / iMaxSendDisorderSize
				+ (listSrcSize % iMaxSendDisorderSize > 0 ? 1 : 0);
		int end = iMaxSendDisorderSize;
		for (int i = 0; i < subs; i++) {
			List<Long> list = null;
			end = ((i == subs - 1) ? listSrc.size() : iMaxSendDisorderSize);
			list = listSrc.subList(0, end);
			sendProt(create.getDos(), iTaskCode27, create.getiCompanyId(),
					packageInfo, list);
			rectProt(create.getDis(), iTaskCode27, list);
		}
	}

	/**
	 * 接收数据<br/>
	 * 
	 * @param dis
	 * @param iTaskCode
	 * @throws IOException
	 */
	private void rectProt(DataInputStream dis, short iTaskCode, List<Long> iLabels)
			throws IOException {
		recHeader(dis);
		if (isTaskCode(iTaskCode)) {
			int iFailedLabelNum = getUnsignedByte(dis.readShort());
			recCheckCode(dis);

			iBack.updateData(true, iLabels, null, 0, iFailedLabelNum);
		} else {
			recFFFF(dis, iTaskCode);
			debugLog(iTaskCode, toStringFFFF());
			if (isFFFF()) {
				errLog(iTaskCode, toStringFFFF());
				if (getiRecResult() == 1) {
					// 服务器错误返回错误码
					iBack.updateData(false, iLabels, "异常(" + getiRecErrcode()
							+ ")", getiRecErrcode(), 0);
				}
			} else {
				errLog(iTaskCode, "rec package err");
			}
		}
	}

	/**
	 * 27.发送协议
	 * 
	 * @param dos
	 * @param iCompanyId
	 * @param iProductId
	 * @param list
	 *            <Map<String, Object>> long iLabelId,int iProduceDate,int
	 *            iBatchNumber
	 * @throws IOException
	 */
	private void sendProt(DataOutputStream dos, short iTaskCode,
			int iCompanyId, Map<String, String> packageInfo,
			List<Long> iLabels) throws IOException {
		int listSize = iLabels.size();

		if (listSize > iMaxSendDisorderSize) {
			errLog(iTaskCode, listSize + "无序批量上传发送超过限制" + iMaxSendDisorderSize);
			return;
		}
		if (listSize <= 0) {
			errLog(iTaskCode, "无数据");
			return;
		}
		short iLabelNumber = (short) listSize;
		long iProductId = Long.valueOf(packageInfo.get(kProdcutId));
		long iPackageID = Long.valueOf(packageInfo.get(kPackageId));
		int iProduceDate = Integer.valueOf(packageInfo.get(kProduceDate));
		int iBatchNumber = Integer.valueOf(packageInfo.get(kBatchNumber));
		int iAread = Integer.valueOf(packageInfo.get(kAreaCode));
		short iOptAction = Short.valueOf(packageInfo.get(kOptAction));
		byte[] OptMemo = packageInfo.get(kOptMemoStr).getBytes();
		short iOptMemSize = (short) OptMemo.length;

		short bodySize = (short) (countBodySize(iCompanyId, iProductId,
				iPackageID, iProduceDate, iBatchNumber, iAread, iOptAction,
				OptMemo, iOptMemSize, iLabelNumber) + listSize * 8);
		sendHeader(dos, iTaskCode, bodySize);
		sendiCompanyId(dos, iCompanyId);
		sendiProductId(dos, iProductId);
		sendiLabel(dos, iPackageID);
		dos.writeInt(iProduceDate);
		dos.writeInt(iBatchNumber);
		sendiAreaCode(dos, iAread);
		dos.writeShort(iOptAction);
		dos.writeShort(iOptMemSize);
		dos.write(OptMemo);
		dos.writeShort(iLabelNumber);
		long label;
		for (int i = 0; i < listSize; i++) {
			label = iLabels.get(i);
			sendiLabel(dos, label);
		}
		sendCheckCode(dos);
	}

}
