package cn.net.cpzslibs.prot.handset;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

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

import cn.net.cpzslibs.prot.ProtBase;
import cn.net.cpzslibs.prot.SocketCreate;
import cn.net.cpzslibs.prot.handset.bean.Product;

/**
 * 17. 根据设备ID获取企业的产品列表.一次发送1000条记录组成的JSon流，直到发完为止
 * 
 * @author zwj
 * 
 *         2014-10-22
 */
public class Prot10061GetProducts extends ProtBase {
	private final short iTaskCode10061 = 2002;
	/**
	 * 产品名称
	 */
	public static final String name = "name";
	/**
	 * 产品id
	 */
	public static final String id = "id";
	/**
	 * 产品型号，用于云南汽配项目 ,Map解析使用
	 */
	public static final String model = "model";
	/**
	 * json解析使用,配件使用车型
	 */
	public static final String cType = "cType";

	public CallBack callBack;
	/**
	 * 判断包标签，是否含有包标签，如果含有包标签true；
	 */
	private boolean isPackage = false;

	/**
	 * 任务号17：获取企业产品列表，设备号无效，iErrCode=0xFFF0
	 */
	public static final int HANDSET_DEVICE_ID_INVALID = 0xFFF0;
	/**
	 * 任务号17：获取企业产品列表，无产品记录，iErrorCode=0xFFEF
	 */
	public static final int HANDSET_NO_PRODUCT = 0xFFEF;
	/**
	 * json数据
	 */
	private String jsonData = "";

	public interface CallBack {
		/**
		 * 
		 * <br/>
		 * 2015-4-3下午4:17:35
		 * 
		 * @param maps
		 *            数据
		 * @param iTotalCount
		 *            总页码
		 * @param iCurrentRecCount
		 *            当前已经接受
		 */
		public void updateData(List<Map<String, String>> maps, int iTotalCount, int iCurrentRecCount);
	}
	public interface CallBack_V2 {

		public void okData(List<Product> products, int iTotalCount, int iCurrentRecCount);
		/**
		 * 
		 * @date 2016-1-25下午12:41:13
		 * @param err
		 *            错误与
		 * @param iRecErrCode
		 *            错误码
		 */
		public void errData(String err, int iRecErrCode);
	}

	/**
	 * 17. 根据设备ID获取企业的产品列表。一次发送1000条记录组成的JSon流，直到发完为止 (1)
	 * 服务器错误时，返回错误状态包，iTaskCode=0xFFFF (2) 设备号无效，iErrCode=0xFFF0 (3)
	 * 无产品记录，iErrorCode=0xFFEF
	 * <p>
	 * 2014-10-31下午3:52:23
	 * </p>
	 * 
	 * @param dos
	 * @param dis
	 * @param context
	 * @param mHandler
	 * @param iTaskCode
	 *            任务id，分为17和1701云南汽配
	 * @throws IOException
	 */
	private void dealProductList(DataOutputStream dos, DataInputStream dis, long iDeviceId, short iTaskCode)
			throws IOException {
		sendProt(dos, iDeviceId, iTaskCode);// 只是请求一次，收取全部数据
		int iCurrentRecCount = 0;
		long totalBodySize = 0;
		int iTotalCount = 0;// 总记录数
		short iCurrPackCount;// 当前包条数
		short iCurrPackNo;// 当前包序号
		do {
			recHeader(dis);
			if (isTaskCode(iTaskCode)) {
				iTotalCount = dis.readInt();// 总记录数
				iCurrPackCount = dis.readShort();// 当前包总记录数
				iCurrPackNo = dis.readShort();// 当前包序号
				iCurrentRecCount = iCurrentRecCount + iCurrPackCount;// 目前接收数量
				// 正确任务
				int bufferLength = getiRecBodySize() - 4 - 2 - 2 - 2;
				byte[] buffer = new byte[bufferLength];
				totalBodySize = totalBodySize + bufferLength;
				for (int i = 0; i < bufferLength; i++) {
					buffer[i] = dis.readByte();
				}

				jsonData = new String(buffer, "utf-8");

				recCheckCode(dis);
			} else {
				// 接收错误的时候，这里接收的是个通用的包
				// 错误任务
				recFFFF(dis, iTaskCode);
				String ret = "下载异常(" + getiRecErrcode() + ")";
				if (getiRecErrcode() == HANDSET_NO_PRODUCT) {
					// 没有产品列表
					ret = "无产品列表";
				}
				// 下载错误
				errLog(iTaskCode, ret);
				break;
			}
			List<Map<String, String>> parseJson = parseProductJson(jsonData, iTaskCode, iCurrPackNo);
			if (isPackage) {
				// 去除包标签的一个数量
				iTotalCount--;
				iCurrentRecCount--;
			}
			callBack.updateData(parseJson, iTotalCount, iCurrentRecCount);
			if (iTotalCount <= iCurrentRecCount) {
				// TODO 这个需要测试下... 下载完成
			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (iTotalCount > iCurrentRecCount);
	}
	/**
	 * 17. 根据设备ID获取企业的产品列表。一次发送1000条记录组成的JSon流，直到发完为止 (1)
	 * 服务器错误时，返回错误状态包，iTaskCode=0xFFFF (2) 设备号无效，iErrCode=0xFFF0 (3)
	 * 无产品记录，iErrorCode=0xFFEF
	 * <p>
	 * 2014-10-31下午3:52:23
	 * </p>
	 * 
	 * @param dos
	 * @param dis
	 * @param context
	 * @param mHandler
	 * @param iTaskCode
	 *            任务id，分为17和1701云南汽配
	 * @throws IOException
	 */
	private void dealProductList_V2(DataOutputStream dos, DataInputStream dis, long iDeviceId, short iTaskCode,
			CallBack_V2 callBack_V2) throws IOException {
		sendProt(dos, iDeviceId, iTaskCode);// 只是请求一次，收取全部数据
		int iCurrentRecCount = 0;
		long totalBodySize = 0;
		int iTotalCount = 0;// 总记录数
		short iCurrPackCount;// 当前包条数
		short iCurrPackNo;// 当前包序号
		do {
			recHeader(dis);
			if (isTaskCode(iTaskCode)) {
				iTotalCount = dis.readInt();// 总记录数
				iCurrPackCount = dis.readShort();// 当前包总记录数
				iCurrPackNo = dis.readShort();// 当前包序号
				iCurrentRecCount = iCurrentRecCount + iCurrPackCount;// 目前接收数量
				// 正确任务
				int bufferLength = getiRecBodySize() - 4 - 2 - 2 - 2;
				byte[] buffer = new byte[bufferLength];
				totalBodySize = totalBodySize + bufferLength;
				for (int i = 0; i < bufferLength; i++) {
					buffer[i] = dis.readByte();
				}

				jsonData = new String(buffer, "utf-8");

				recCheckCode(dis);
			} else {
				// 接收错误的时候，这里接收的是个通用的包
				// 错误任务
				recFFFF(dis, iTaskCode);
				String ret = "下载异常(" + getiRecErrcode() + ")";
				if (getiRecErrcode() == HANDSET_NO_PRODUCT) {
					// 没有产品列表
					ret = "无产品列表";
				}
				// 下载错误
				errLog(iTaskCode, ret);
				callBack_V2.errData(ret, getiRecErrcode());
				break;
			}
			List<Product> parseJson = parseProductJson_V2(jsonData);
			if (isPackage) {
				// 去除包标签的一个数量
				iTotalCount--;
				iCurrentRecCount--;
			}
			callBack_V2.okData(parseJson, iTotalCount, iCurrentRecCount);
			if (iTotalCount <= iCurrentRecCount) {
				// TODO 这个需要测试下... 下载完成
			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (iTotalCount > iCurrentRecCount);
	}

	private void sendProt(DataOutputStream dos, long DeviceId, short iTaskCode) throws IOException {
		short bodySize = countBodySize(DeviceId);
		sendHeader(dos, iTaskCode, bodySize);
		// 发送公司标签
		dos.writeLong(DeviceId);
		sendCheckCode(dos);
	}

	/**
	 * json解析
	 * 
	 * @param jsonData
	 *            解析数据
	 * @param parseModel
	 *            解析模式
	 * @return [{"id":"XXX","name":"XXX","nid":"XXX","cType":"XXX"} …]<br/>
	 */
	public List<Map<String, String>> parseProductJson(String jsonData, short parseModel, int iCurrPackNo) {
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		return list;
	}
	/**
	 * json解析
	 * 
	 * @param jsonData
	 *            解析数据
	 * @param parseModel
	 *            解析模式
	 * @return [{"id":"XXX","name":"XXX"} …]
	 */
	private List<Product> parseProductJson_V2(String jsonData) {
		List<Product> products = new ArrayList<Product>();
		Gson gson = new Gson();
		JsonParser parser = new JsonParser();
		JsonArray jsonArray = parser.parse(jsonData).getAsJsonArray();
		int size = jsonArray.size();
		for (int i = 0; i < size; i++) {
			JsonElement jsonElement = jsonArray.get(i);
			Product product = gson.fromJson(jsonElement, Product.class);
			products.add(product);
		}
		return products;
	}

	/**
	 * 产品列表下载
	 * 
	 * @param dos
	 * @param dis
	 * @param context
	 * @param mHandler
	 * @throws IOException
	 */
	/*public void dealCarProductList(SocketCreate create, long iDeviceId, CallBack callBack) throws IOException {
		this.iSendTaskIndex = create.getiTaskIndex();
		this.callBack = callBack;
		dealProductList(create.getDos(), create.getDis(), iDeviceId, iTaskCode_car1701);
	}*/

	/**
	 * 下载产品列表
	 * 
	 * @date 2016-1-25下午1:17:52
	 * @param create
	 * @param iDeviceId
	 *            设备号
	 * @param callBack
	 *            [{"id":"XXX","name":"XXX"} …]
	 * @throws IOException
	 */
	public void dealProductList(SocketCreate create, long iDeviceId, CallBack callBack) throws IOException {
		this.iSendTaskIndex = create.getiTaskIndex();
		this.callBack = callBack;
		dealProductList(create.getDos(), create.getDis(), iDeviceId, iTaskCode10061);
	}
	/**
	 * 下载产品列表
	 * 
	 * @date 2016-1-25下午1:18:17
	 * @param create
	 * @param iDeviceId
	 * @param callBack
	 * @throws IOException
	 */
	public void dealProductList_V2(SocketCreate create, CallBack_V2 callBack) throws IOException {
		this.iSendTaskIndex = create.getiTaskIndex();
		dealProductList_V2(create.getDos(), create.getDis(), create.getiDeviceId(), iTaskCode10061, callBack);
	}


	/**
	 * 测试使用。获取到json数据 <br/>
	 * 2015-4-30下午1:46:28
	 * 
	 * @return
	 */
	public String getJsonData() {
		return jsonData;
	}

}
