package com.huatek.busi.ws;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import javax.jws.WebService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.huatek.busi.ws.protocol.CacDataNode;
import com.huatek.busi.ws.protocol.CacMonitorData;
import com.huatek.busi.ws.protocol.CacRequest;
import com.huatek.busi.ws.util.CacParseFactory;
import com.huatek.busi.ws.util.CacUtil;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.ConversionException;

/**
 * CAC WebService接口实现
 *
 * @author anker cheng
 *
 * @Date 2019年6月26日
 */
@WebService(endpointInterface = "com.huatek.busi.ws.XydlService")
public class XydlServiceImpl implements XydlService {
    private static final Logger logger = LoggerFactory.getLogger(XydlServiceImpl.class);
    private static final XStream XSTREAM;
    static {
        XSTREAM = new XStream();
        // XSTREAM = new XStream(new DomDriver());
        // XSTREAM = new XStream(new StaxDriver());
        // 使用注解
        XSTREAM.processAnnotations(CacRequest.class);
        // 去掉容器——集合“剥皮”
        XSTREAM.addImplicitCollection(CacMonitorData.class, "cacDataNode");
    }

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private CacParseFactory cacParseFactory;

    @Override
    public String uploadCACData(String strXMLParams) {
        if(StringUtils.isEmpty(strXMLParams)) {
            logger.error("strXMLParams is empty!");
            return CacUtil.buildResult();
        }
        logger.info(strXMLParams.replace("\r", "").replace("\n", "").trim());
        try {
            // 解析
            CacRequest request = (CacRequest) XSTREAM.fromXML(strXMLParams);
            List<CacDataNode> cacDataNodeList = request.getCacMonitorData().getCacDataNode();
            if (CollectionUtils.isEmpty(cacDataNodeList)) {
                return CacUtil.buildResult();
            }
            CompletableFuture<Void> completableFuture = CompletableFuture.allOf(cacDataNodeList
                    .stream().map(cacDataNode -> CompletableFuture
                            .supplyAsync(() -> cacParseFactory.parse(request, cacDataNode), taskExecutor))
                    .toArray(CompletableFuture[]::new));
            completableFuture.get();
            return CacUtil.buildResult();
        } catch (ConversionException e) {
            logger.error(e.getMessage());
            return CacUtil.buildResult();
        }  catch (InterruptedException | ExecutionException e) {
            logger.error("parse error", e);
            return CacUtil.buildResult();
        } catch (Exception e) {
            logger.error("parse error", e);
            return CacUtil.buildResult();
        }
    }
}