package com.uas.search.console.jms;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.uas.search.console.dao.BrandSimpleInfoDao;
import com.uas.search.console.dao.ComponentSimpleInfoDao;
import com.uas.search.console.dao.KindSimpleInfoDao;
import com.uas.search.console.dao.OrderInvoiceSimpleInfoDao;
import com.uas.search.console.dao.OrderSimpleInfoDao;
import com.uas.search.console.dao.PurchaseInvoiceSimpleInfoDao;
import com.uas.search.console.dao.PurchaseSimpleInfoDao;
import com.uas.search.console.model.BrandSimpleInfo;
import com.uas.search.console.model.ComponentSimpleInfo;
import com.uas.search.console.model.KindSimpleInfo;
import com.uas.search.console.model.OrderInvoiceSimpleInfo;
import com.uas.search.console.model.OrderSimpleInfo;
import com.uas.search.console.model.ParsedQueueMessage;
import com.uas.search.console.model.PurchaseInvoiceSimpleInfo;
import com.uas.search.console.model.PurchaseSimpleInfo;
import com.uas.search.console.util.SearchConstants;

/**
 * 对得到的队列消息进行解析的工具
 * 
 * @author sunyj
 * @since 2016年7月7日 下午6:14:03
 */
@Service
public class QueueMessageParser {

	@Autowired
	private KindSimpleInfoDao kindDao;

	@Autowired
	private BrandSimpleInfoDao brandDao;

	@Autowired
	private ComponentSimpleInfoDao componentDao;

	@Autowired
	private OrderSimpleInfoDao orderDao;

	@Autowired
	private OrderInvoiceSimpleInfoDao orderInvoiceDao;

	@Autowired
	private PurchaseSimpleInfoDao purchaseDao;

	@Autowired
	private PurchaseInvoiceSimpleInfoDao purchaseInvoiceDao;

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

	/**
	 * 对得到的json消息进行解析
	 * 
	 * @param message
	 * @return ParsedQueueMessage对象
	 * @throws JSONException
	 */
	// {"method":"value1","table":"value2","param1":"value3","param2":"value4"}
	public ParsedQueueMessage parse(String message) throws JSONException {
		if (StringUtils.isEmpty(message) || message.equals("{}")) {
			return null;
		}
		ParsedQueueMessage parsedQueueMessage = new ParsedQueueMessage();
		JSONObject jsonObject = JSONObject.parseObject(message);

		// 解析数据库表的更改类型
		String method = jsonObject.getString("method");
		if (method.equals("insert")) {
			parsedQueueMessage.setMethodType(ParsedQueueMessage.INSERT);
		}

		else if (method.equals("update")) {
			parsedQueueMessage.setMethodType(ParsedQueueMessage.UPDATE);
		}

		else if (method.equals("delete")) {
			parsedQueueMessage.setMethodType(ParsedQueueMessage.DELETE);
		} else {
			return null;
		}

		// 解析哪个表有更改
		Object[] objects = null;
		String table = jsonObject.getString("table");
		try {
			if (table.equals(SearchConstants.KIND_TABLE_NAME)) {
				objects = parseKind(jsonObject);
			} else if (table.equals(SearchConstants.BRAND_TABLE_NAME)) {
				objects = parseBrand(jsonObject);
			} else if (table.equals(SearchConstants.COMPONENT_TABLE_NAME)) {
				objects = parseComponent(jsonObject);
			} else if (table.equals(SearchConstants.ORDER_TABLE_NAME)) {
				objects = parseOrder(jsonObject);
			} else if (table.equals(SearchConstants.ORDER_INVOICE_TABLE_NAME)) {
				objects = parseOrderInvoice(jsonObject);
			} else if (table.equals(SearchConstants.PURCHASE_TABLE_NAME)) {
				objects = parsePurchase(jsonObject);
			} else if (table.equals(SearchConstants.PURCHASE_INVOICE_TABLE_NAME)) {
				objects = parsePurchaseInvoice(jsonObject);
			} else {
				return null;
			}
		} catch (Exception e) {
			// 防止SQLRecoverableException导致应用终止
			logger.error("", e);
			return null;
		}

		parsedQueueMessage.setObjects(objects);
		return parsedQueueMessage;
	}

	/**
	 * 对kind类目进行解析
	 * 
	 * @param jsonObject
	 * @return kind类目对象数组
	 * @throws JSONException
	 */
	// {"method":"insert","table":"product$kind","ids":[2400,1299]}
	private KindSimpleInfo[] parseKind(JSONObject jsonObject) throws JSONException {
		Set<Long> ids = getIds(jsonObject.getJSONArray("ids"));
		List<KindSimpleInfo> kindsList = new ArrayList<>();
		// delete操作
		// 删除后数据库中可能已经没有相应数据了，无法通过dao获取，需要手动创建对象
		if (jsonObject.getString("method").equalsIgnoreCase("delete")) {
			for (Long id : ids) {
				KindSimpleInfo kind = new KindSimpleInfo();
				kind.setId(id);
				kindsList.add(kind);
			}
		} else {
			kindsList = kindDao.findAll(ids);
		}
		KindSimpleInfo[] kinds = new KindSimpleInfo[kindsList.size()];
		kindsList.toArray(kinds);
		return kinds;
	}

	/**
	 * 对brand品牌进行解析
	 * 
	 * @param jsonObject
	 * @return brand品牌对象数组
	 * @throws JSONException
	 */
	// {"method":"insert","table":"product$brand","ids":[124]}
	private BrandSimpleInfo[] parseBrand(JSONObject jsonObject) throws JSONException {
		Set<Long> ids = getIds(jsonObject.getJSONArray("ids"));
		List<BrandSimpleInfo> brandsList = new ArrayList<>();
		if (jsonObject.getString("method").equalsIgnoreCase("delete")) {
			for (Long id : ids) {
				BrandSimpleInfo brand = new BrandSimpleInfo();
				brand.setId(id);
				brandsList.add(brand);
			}
		} else {
			brandsList = brandDao.findAll(ids);
		}
		BrandSimpleInfo[] brands = new BrandSimpleInfo[brandsList.size()];
		brandsList.toArray(brands);
		return brands;
	}

	/**
	 * 对component器件进行解析
	 * 
	 * @param jsonObject
	 * @return component器件对象数组
	 * @throws JSONException
	 */
	// {"method":"value1","table":"product$component","ids":[1024]}
	private ComponentSimpleInfo[] parseComponent(JSONObject jsonObject) throws JSONException {
		Set<Long> ids = getIds(jsonObject.getJSONArray("ids"));
		List<ComponentSimpleInfo> componentsList = new ArrayList<>();
		if (jsonObject.getString("method").equalsIgnoreCase("delete")) {
			for (Long id : ids) {
				ComponentSimpleInfo component = new ComponentSimpleInfo();
				component.setId(id);
				componentsList.add(component);
			}
		} else {
			componentsList = componentDao.findAll(ids);
		}
		ComponentSimpleInfo[] components = new ComponentSimpleInfo[componentsList.size()];
		componentsList.toArray(components);
		return components;
	}

	/**
	 * 对销售单进行解析
	 * 
	 * @param jsonObject
	 * @return 销售单对象数组
	 * @throws JSONException
	 */
	// {"method":"insert","table":"trade$order","ids":[124]}
	private OrderSimpleInfo[] parseOrder(JSONObject jsonObject) throws JSONException {
		Set<Long> ids = getIds(jsonObject.getJSONArray("ids"));
		List<OrderSimpleInfo> ordersList = new ArrayList<>();
		if (jsonObject.getString("method").equalsIgnoreCase("delete")) {
			for (Long id : ids) {
				OrderSimpleInfo order = new OrderSimpleInfo();
				order.setId(id);
				ordersList.add(order);
			}
		} else {
			ordersList = orderDao.findAll(ids);
		}
		OrderSimpleInfo[] orders = new OrderSimpleInfo[ordersList.size()];
		ordersList.toArray(orders);
		return orders;
	}

	/**
	 * 对销售发货单进行解析
	 * 
	 * @param jsonObject
	 * @return 销售发货单对象数组
	 * @throws JSONException
	 */
	// {"method":"insert","table":"trade$invoice_fmor","ids":[124]}
	private OrderInvoiceSimpleInfo[] parseOrderInvoice(JSONObject jsonObject) throws JSONException {
		Set<Long> ids = getIds(jsonObject.getJSONArray("ids"));
		List<OrderInvoiceSimpleInfo> orderInvoicesList = new ArrayList<>();
		if (jsonObject.getString("method").equalsIgnoreCase("delete")) {
			for (Long id : ids) {
				OrderInvoiceSimpleInfo orderInvoice = new OrderInvoiceSimpleInfo();
				orderInvoice.setId(id);
				orderInvoicesList.add(orderInvoice);
			}
		} else {
			orderInvoicesList = orderInvoiceDao.findAll(ids);
		}
		OrderInvoiceSimpleInfo[] orderInvoices = new OrderInvoiceSimpleInfo[orderInvoicesList.size()];
		orderInvoicesList.toArray(orderInvoices);
		return orderInvoices;
	}

	/**
	 * 对采购单进行解析
	 * 
	 * @param jsonObject
	 * @return 采购单对象数组
	 * @throws JSONException
	 */
	// {"method":"insert","table":"trade$purchase","ids":[124]}
	private PurchaseSimpleInfo[] parsePurchase(JSONObject jsonObject) throws JSONException {
		Set<Long> ids = getIds(jsonObject.getJSONArray("ids"));
		List<PurchaseSimpleInfo> purchasesList = new ArrayList<>();
		if (jsonObject.getString("method").equalsIgnoreCase("delete")) {
			for (Long id : ids) {
				PurchaseSimpleInfo purchase = new PurchaseSimpleInfo();
				purchase.setId(id);
				purchasesList.add(purchase);
			}
		} else {
			purchasesList = purchaseDao.findAll(ids);
		}
		PurchaseSimpleInfo[] purchases = new PurchaseSimpleInfo[purchasesList.size()];
		purchasesList.toArray(purchases);
		return purchases;
	}

	/**
	 * 对采购发货单进行解析
	 * 
	 * @param jsonObject
	 * @return 采购发货单对象数组
	 * @throws JSONException
	 */
	// {"method":"insert","table":"trade$invoice_fmpu","ids":[124]}
	private PurchaseInvoiceSimpleInfo[] parsePurchaseInvoice(JSONObject jsonObject) throws JSONException {
		Set<Long> ids = getIds(jsonObject.getJSONArray("ids"));
		List<PurchaseInvoiceSimpleInfo> purchaseInvoicesList = new ArrayList<>();
		if (jsonObject.getString("method").equalsIgnoreCase("delete")) {
			for (Long id : ids) {
				PurchaseInvoiceSimpleInfo purchaseInvoice = new PurchaseInvoiceSimpleInfo();
				purchaseInvoice.setId(id);
				purchaseInvoicesList.add(purchaseInvoice);
			}
		} else {
			purchaseInvoicesList = purchaseInvoiceDao.findAll(ids);
		}
		PurchaseInvoiceSimpleInfo[] purchaseInvoices = new PurchaseInvoiceSimpleInfo[purchaseInvoicesList.size()];
		purchaseInvoicesList.toArray(purchaseInvoices);
		return purchaseInvoices;
	}

	/**
	 * 从队列消息中获取id（同时消除重复id）
	 * 
	 * @param jsonArray
	 *            队列消息中json格式的id
	 * @return
	 */
	private Set<Long> getIds(JSONArray jsonArray) {
		if (jsonArray == null || jsonArray.isEmpty()) {
			return null;
		}
		Object[] ids = jsonArray.toArray();
		Set<Long> idsSet = new HashSet<>();
		for (int i = 0; i < ids.length; i++) {
			idsSet.add(Long.parseLong(ids[i].toString()));
		}
		return idsSet;
	}
}
