package com.yihu.hos.standard.service.adapter;

import com.fasterxml.jackson.databind.JsonNode;
import com.yihu.hos.common.XmlUtil;
import com.yihu.hos.core.datatype.CollectionUtil;
import com.yihu.hos.core.datatype.StringUtil;
import com.yihu.hos.standard.model.adapter.AdapterSchemeModel;
import com.yihu.hos.standard.model.adapter.AdapterSchemeVersionModel;
import com.yihu.hos.standard.model.adapter.resultModel.AdapterSchemeResultDetailModel;
import com.yihu.hos.standard.model.adapter.resultModel.AdapterSchemeResultModel;
import com.yihu.hos.standard.model.standard.StandardModel;
import com.yihu.hos.standard.model.standard.StandardVersionModel;
import com.yihu.hos.web.framework.constant.SqlConstants;
import com.yihu.hos.web.framework.dao.SQLGeneralDAO;
import com.yihu.hos.web.framework.model.DetailModelResult;
import com.yihu.hos.web.framework.model.Result;
import org.dom4j.Document;
import org.dom4j.Element;
import org.hibernate.Query;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;

import static antlr.build.ANTLR.root;

/**
 * @created lingfeng 2015/12/25.
 */
@Transactional
@Service("AdapterSchemeService")
public class AdapterSchemeService extends SQLGeneralDAO {

    public static final String BEAN_ID = "AdapterSchemeService";

    public DetailModelResult getEntityList(String query, String order, Integer limit, Integer offset) {
        try {
            List list = getEntityList(AdapterSchemeModel.class, query, order, limit, offset);
            DetailModelResult detailModelResult = DetailModelResult.success("获取适配列表成功");
            detailModelResult.setDetailModelList(list);
            return detailModelResult;
        } catch (Exception e) {
            DetailModelResult detailModelResult = DetailModelResult.error("获取适配列表失败");
            return detailModelResult;
        }
    }

    public Result add(String scheme) {
        Boolean existFlg = false;
        try {
            AdapterSchemeModel model = objectMapper.readValue(scheme, AdapterSchemeModel.class);
            existFlg = schemeNameValidate(model.getName());
            if (!existFlg) {
                model.setStatus(0);
                saveEntity(model);
            }
            model.setSuccessFlg(true);
            model.setMessage("保存适配方案成功");
            return model;
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (existFlg) {
            return Result.error("已存在相同适配方案名");
        } else {
            return Result.error("保存适配方案失败");
        }
    }

    public Boolean schemeNameValidate(String name) {
        String sql = "FROM AdapterSchemeModel WHERE name = :name";
        Query query = getCurrentSession().createQuery(sql);
        query.setParameter("name", name);
        List<AdapterSchemeModel> list = query.list();
        if (!CollectionUtil.isEmpty(list)) {
            return true;
        }
        return false;
    }

    public Result delete(Integer schemeId) {
        Boolean existFlg = false;
        try {
            AdapterSchemeModel model = getEntity(AdapterSchemeModel.class, schemeId);
            existFlg = existSchemeVersionValid(schemeId);
            if (!existFlg) {
                deleteEntity(model);
                return Result.success("删除适配方案成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (existFlg) {
            return Result.error("已存在适配方案版本");
        } else {
            return Result.error("删除适配方案成功失败");
        }
    }

    public Boolean schemeNameValidate(Integer schemeId, String name) {
        String sql = "FROM AdapterSchemeModel WHERE name = :name and id != :schemeId";
        Query query = getCurrentSession().createQuery(sql);
        query.setParameter("name", name);
        query.setParameter("schemeId", schemeId);
        List<AdapterSchemeModel> list = query.list();
        if (!CollectionUtil.isEmpty(list)) {
            return true;
        }
        return false;
    }

    public Result update(String scheme) {
        Boolean existFlg = false;
        try {
            AdapterSchemeModel model = objectMapper.readValue(scheme, AdapterSchemeModel.class);
            existFlg = schemeNameValidate(model.getId(), model.getName());
            if (!existFlg) {
                updateEntity(model);
                model.setSuccessFlg(true);
                model.setMessage("修改适配方案成功");
                return model;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (existFlg) {
            return Result.error("已存在适配方案名称");
        } else {
            return Result.error("修改适配方案失败");
        }
    }

    public Result get(Integer schemeId) {
        try {
            AdapterSchemeModel model = getEntity(AdapterSchemeModel.class, schemeId);
            model.setSuccessFlg(true);
            model.setMessage("获取适配成功");
            return model;
        } catch (Exception e) {
            return Result.error("获取适配成功");
        }
    }

    public DetailModelResult getSchemeList(String condition) {
        try {
            String name = SqlConstants.EMPTY;
            if (!StringUtil.isEmpty(condition)) {
                try {
                    JsonNode jsonNode = objectMapper.readTree(condition);
                    if (jsonNode.get("name") != null) {
                        name = jsonNode.get("name").asText();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            String schemeHql = "FROM AdapterSchemeModel";
            Query query = getCurrentSession().createQuery(schemeHql);
            List<AdapterSchemeModel> adapterSchemeModelList = query.list();
            List<Integer> schemeIdList = new ArrayList<>();
            List<Integer> stdIdList = new ArrayList<>();
            List<String> versionList = new ArrayList<>();
            Map<Integer, AdapterSchemeVersionModel> schemeVersionMap = new HashMap<>();
            Map<Integer, StandardModel> stdMap = new HashMap<>();
            Map<String, StandardVersionModel> stdVersionMap = new HashMap<>();

            for (AdapterSchemeModel adapterSchemeModel : adapterSchemeModelList) {
                schemeIdList.add(adapterSchemeModel.getId());
                stdIdList.add(adapterSchemeModel.getStdId());
                stdIdList.add(adapterSchemeModel.getAdapterStdId());
                versionList.add(adapterSchemeModel.getStdVersion());
                versionList.add(adapterSchemeModel.getAdapterStdVersion());
            }
//            versionList = delDuplicateArr(versionList);
            if (CollectionUtil.isEmpty(schemeIdList)) {
                schemeIdList.add(null);
            }
            if (CollectionUtil.isEmpty(stdIdList)) {
                stdIdList.add(null);
            }
            if (CollectionUtil.isEmpty(versionList)) {
                versionList.add(SqlConstants.EMPTY);
            }

            String adapterVersionHql = "FROM AdapterSchemeVersionModel WHERE schemeId IN :schemeIdList";
            query = getCurrentSession().createQuery(adapterVersionHql);
            query.setParameterList("schemeIdList", schemeIdList);
            List<AdapterSchemeVersionModel> versionModelList = query.list();
            for (AdapterSchemeVersionModel model : versionModelList) {
                schemeVersionMap.put(model.getId(), model);
            }

            String standardHql = "FROM StandardModel WHERE id IN :stdIdList";
            query = getCurrentSession().createQuery(standardHql);
            query.setParameterList("stdIdList", stdIdList);
            List<StandardModel> stdModelList = query.list();
            for (StandardModel model : stdModelList) {
                stdMap.put(model.getId(), model);
            }

            String stdVersionHql = "FROM StandardVersionModel WHERE version IN :versionList";
            query = getCurrentSession().createQuery(stdVersionHql);
            query.setParameterList("versionList", versionList);
            List<StandardVersionModel> stdVersionList = query.list();
            for (StandardVersionModel model : stdVersionList) {
                stdVersionMap.put(model.getVersion(), model);
            }

            List<AdapterSchemeResultDetailModel> resultDetailModelList = new ArrayList<>();
            Map<String, AdapterSchemeResultDetailModel> resultDetailModelMap = new HashMap<>();
            Map<String, AdapterSchemeResultDetailModel> resultDetailModelCheckMap = new HashMap<>();
            Map<String, AdapterSchemeResultDetailModel> resultDetailModelAddMap = new HashMap<>();

            for (AdapterSchemeModel schemeModel : adapterSchemeModelList) {
                String id = "scheme" + schemeModel.getId();
                AdapterSchemeResultDetailModel resultDetailModel = new AdapterSchemeResultDetailModel();
                resultDetailModel.setId(id);
                resultDetailModel.setPid("");
                resultDetailModel.setType(0);
                resultDetailModel.setName(schemeModel.getName());
                resultDetailModel.setStdName(stdMap.get(schemeModel.getStdId()).getName());
                resultDetailModel.setStdVersion(stdVersionMap.get(schemeModel.getStdVersion()).getVersion());
                resultDetailModel.setStdVersionName(stdVersionMap.get(schemeModel.getStdVersion()).getName());
                resultDetailModel.setStdPublisher(stdMap.get(schemeModel.getStdId()) == null ? "" : stdMap.get(schemeModel.getStdId()).getPublisher());
                resultDetailModel.setPublisher(stdMap.get(schemeModel.getAdapterStdId()) == null ? "" : stdMap.get(schemeModel.getAdapterStdId()).getPublisher());
                resultDetailModel.setAdapterName(stdMap.get(schemeModel.getAdapterStdId()) == null ? "" : stdMap.get(schemeModel.getAdapterStdId()).getName());
                if (stdVersionMap.get(schemeModel.getAdapterStdVersion()) != null) {
                    resultDetailModel.setAdapterVersionName(stdVersionMap.get(schemeModel.getAdapterStdVersion()).getName());
                    resultDetailModel.setAdapterStdVersion(stdVersionMap.get(schemeModel.getAdapterStdVersion()).getVersion());
                }
                if (StringUtil.isEmpty(name) || schemeModel.getName().contains(name)) {
                    resultDetailModelCheckMap.put(id, resultDetailModel);
                    resultDetailModelAddMap.put(id, resultDetailModel);
                    resultDetailModelList.add(resultDetailModel);
                }
                resultDetailModelMap.put(id, resultDetailModel);
            }

            for (AdapterSchemeVersionModel versionModel : versionModelList) {
                String pid = "scheme" + versionModel.getSchemeId();
                String id = "version" + versionModel.getId();
                AdapterSchemeResultDetailModel resultDetailModel = new AdapterSchemeResultDetailModel();
                resultDetailModel.setId(id);
                resultDetailModel.setPid(pid);
                resultDetailModel.setName(versionModel.getName());
                resultDetailModel.setStatus(versionModel.getPublishStatus());
                resultDetailModel.setDate(StringUtil.toString(versionModel.getPublishTime()));
                resultDetailModel.setVersion(versionModel.getVersion());
                resultDetailModel.setType(1);
                if (resultDetailModelCheckMap.containsKey(pid)) {
                    resultDetailModel.setAdapterStdVersion(resultDetailModelCheckMap.get(resultDetailModel.getPid()).getAdapterStdVersion());
                    resultDetailModelList.add(resultDetailModel);
                } else if (StringUtil.isEmpty(name) || versionModel.getName().contains(name)) {
                    resultDetailModelList.add(resultDetailModel);
                    if (!resultDetailModelAddMap.containsKey(pid)) {
                        resultDetailModelAddMap.put(pid, resultDetailModelMap.get(resultDetailModel.getPid()));
                        resultDetailModelList.add(resultDetailModelMap.get(resultDetailModel.getPid()));
                    }
                }
            }
            DetailModelResult detailModelResult = DetailModelResult.success("获取适配方案成功");
            detailModelResult.setDetailModelList(resultDetailModelList);
            return detailModelResult;
        } catch (Exception e) {
            e.printStackTrace();
            return DetailModelResult.error("获取适配方案失败");
        }

    }

    public boolean existSchemeVersionValid(Integer schemeId) {
        String hql = "FROM AdapterSchemeVersionModel WHERE schemeId = :schemeId";
        Query query = getCurrentSession().createQuery(hql);
        query.setParameter("schemeId", schemeId);
        List<AdapterSchemeVersionModel> schemeVersionModelList = query.list();
        if (!CollectionUtil.isEmpty(schemeVersionModelList)) {
            return true;
        }
        return false;
    }

    public DetailModelResult getAdapterSchemeResultModelList() {
        String schemeHql = "FROM AdapterSchemeModel";
        Query query = getCurrentSession().createQuery(schemeHql);
        List<AdapterSchemeModel> adapterSchemeModelList = query.list();
        List<AdapterSchemeResultModel> schemeList = new ArrayList<>();
        DetailModelResult result = new DetailModelResult();
        for (AdapterSchemeModel schemeModel : adapterSchemeModelList) {
            String adapterVersionHql = "FROM AdapterSchemeVersionModel WHERE schemeId = :schemeId and publishStatus = 1";
            query = getCurrentSession().createQuery(adapterVersionHql);
            query.setParameter("schemeId", schemeModel.getId());
            List<AdapterSchemeVersionModel> versionModelList = query.list();
            if (versionModelList.size() > 0) {
                AdapterSchemeResultModel resultDetailModel = new AdapterSchemeResultModel();
                resultDetailModel.setSchemeId(schemeModel.getId());
                resultDetailModel.setName(schemeModel.getName());
                resultDetailModel.setVersionList(versionModelList);
                schemeList.add(resultDetailModel);
            }
        }
        result.setDetailModelList(schemeList);
        return result;
    }

    public List delDuplicateArr(List<?> list) {
        // 利用 Set 的特性，将所有项目放入 Set
        //中即可移除重复的项目
        Set<Object> set = new HashSet<>();
        for (Object element : list) {
            set.add(element);
        }
        // Set.size() 为不重复项目的个数
        List nonDuplicateArra = new ArrayList();
        // 将 Set 中的项目取出放到 nonDuplicateArray 中
        Object[] tempArray = set.toArray();
        for (int i = 0; i < tempArray.length; i++) {
            nonDuplicateArra.add(tempArray[i]);
        }
        return nonDuplicateArra;
    }

    /**
     * 转换适配方案为华三的 XML 数据格式，一个表对应一个华三 XML。
     * @return
     */
    public List<Document> fillH3CDiJobXml() {
        List<Document> docList = new ArrayList<>();
        try {
            Document tmplDoc = XmlUtil.xml2doc(new ClassPathResource("/template/h3c-di-job.xml").getFile().getPath());
            Element rootElement = tmplDoc.getRootElement();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return docList;
    }

}
