package com.sagacloud.dict;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sagacloud.utils.CommonUtil;
import com.sagacloud.utils.OssUtils;
import com.sagacloud.utils.jsonHelper.facility.Facility;
import com.sagacloud.utils.tables.CtmNodeTable;
import com.sagacloud.utils.tables.HBaseTable;
import org.apache.htrace.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * Created by wo on 5/18/17.
 */
public class EqStaticInfo {
    private static final Logger log = LoggerFactory.getLogger(EqStaticInfo.class);

    private static Set<String> sysSet = new HashSet<>();//系统编码
    private Set<String> dSysSet = new HashSet<>();
    private static Set<String> eqSet = new HashSet<>();//设备编码
    private Set<String> dEqSet = new HashSet<>();
    private static Set<String> ecSet = new HashSet<>();//6位部件编码
    private Set<String> dEcSet = new HashSet<>();
    private static Set<String> familySet = new HashSet<>();//种族编码
    private Set<String> dFamilySet = new HashSet<>();

    //两位系统编码、四位设备编码、六位部件编码 --> 两位专业编码
    private static Map<String, String> cateToMajorMap = new HashMap<>();
    private Map<String, String> dCateToMajorMap = new HashMap<>();

    //两位系统编码、三位(设备/部件)种族编码、四位设备编码、六位部件编码 --> 系统、种族、设备、部件名称
    private static Map<String, String> cateToNameMap = new HashMap<>();
    private Map<String, String> dCateToNameMap = new HashMap<>();

    //两位专业编码 --> 专业名称
    private static Map<String, String> majorCodeToNameMap = new HashMap<>();
    private Map<String, String> dMajorCodeToNameMap = new HashMap<>();

    //四位设备编码、六位部件编码 --> 三位(设备/部件)种族编码
    private static Map<String, String> eqToFamilyMap = new HashMap<>();
    private Map<String, String> dEqToFamilyMap = new HashMap<>();

    //两位专业编码->两位系统编码
    private static Map<String,Set<String>> majorToSysMap = new HashMap<>();
    private Map<String,Set<String>> dMajorToSysMap = new HashMap<>();

    //两位专业编码->四位设备编码
    private static Map<String,Set<String>> majorToEqMap = new HashMap<>();
    private Map<String,Set<String>> dMajorToEqMap = new HashMap<>();


    //两位系统编码->包含的四位设备编码
    public static Map<String,Set<String>> systemToEqMap = new HashMap<>();

    //自定义字典的所有节点
    private JSONArray ctmNodeArr;

    // 数据平台自己定义的资产通用信息点
    public static Set<String> propertyGeneralInfos = CommonUtil.createSet("DPManufacturerID", "DPSpecificationID", "DPBrandID",
            "DPSupplierID", "DPInsurerID", "DPMaintainerID");
    static {
        init();
    }

    private static void clearAll(){
        majorCodeToNameMap = new HashMap<>();
        majorToSysMap = new HashMap<>();
        cateToMajorMap = new HashMap<>();
        cateToNameMap = new HashMap<>();
        majorToEqMap = new HashMap<>();
        eqSet = new HashSet<>();
        systemToEqMap = new HashMap<>();
        ecSet = new HashSet<>();
        sysSet = new HashSet<>();
        familySet = new HashSet<>();
        eqToFamilyMap = new HashMap<>();
    }

    public static void init(){
        try {
            clearAll();
            //构建 专业-系统-设备-部件 层级关系
            String jsonStr = OssUtils.getFileAsString("property/Dictionary/Facility_new.json");
            ObjectMapper mapper = new ObjectMapper();
            Facility fac = mapper.readValue(jsonStr, Facility.class);
            fac.getAll().stream().forEach(facilityClass -> {
                majorCodeToNameMap.put(facilityClass.getCode(), facilityClass.getName());
                facilityClass.getContent().stream().forEach(fsys -> {
                    sysSet.add(fsys.getCode());
                    if (!majorToSysMap.containsKey(facilityClass.getCode()))
                        majorToSysMap.put(facilityClass.getCode(), new HashSet<>());
                    Set<String> tempSysSet = majorToSysMap.get(facilityClass.getCode());
                    tempSysSet.add(fsys.getCode());
                    cateToMajorMap.put(fsys.getCode(), facilityClass.getCode());
                    cateToNameMap.put(fsys.getCode(), fsys.getSystem());
                    fsys.getContent().stream().forEach(eq -> {
                        if (!majorToEqMap.containsKey(facilityClass.getCode())) {
                            majorToEqMap.put(facilityClass.getCode(), new HashSet<>());
                        }
                        Set<String> tempEqSet = majorToEqMap.get(facilityClass.getCode());
                        tempEqSet.add(eq.getCode());
                        eqSet.add(eq.getCode());
                        if(!systemToEqMap.containsKey(fsys.getCode())){
                            systemToEqMap.put(fsys.getCode(), new HashSet<>());
                        }
                        systemToEqMap.get(fsys.getCode()).add(eq.getCode());
                        cateToMajorMap.put(eq.getCode(), facilityClass.getCode());
                        cateToNameMap.put(eq.getCode(), eq.getFacility());
                        if (eq.getComponents() != null) {
                            eq.getComponents().stream().forEach(ec -> {
                                ecSet.add(ec.getCode());
                                cateToMajorMap.put(ec.getCode(), facilityClass.getCode());
                                cateToNameMap.put(ec.getCode(), ec.getComponent());
                            });
                        }
                    });
                });
            });

            //构建 种族-设备/部件 关系
            String familyPath = "property/Dictionary/EqFamily.json";
            jsonStr =  OssUtils.getFileAsString(familyPath);
            JSONObject json = JSONObject.parseObject(jsonStr);
            JSONArray outterContent = json.getJSONArray("all");
            for (int i = 0; i < outterContent.size(); ++i) {
                JSONObject familyNode = outterContent.getJSONObject(i);
                String familyCode = familyNode.getString("code");
//                familyMap.put(familyCode,true);
                familySet.add(familyCode);
                cateToNameMap.put(familyCode, familyNode.getString("name"));
                if (familyNode.get("content") == null) continue;
                JSONArray innerContent = familyNode.getJSONArray("content");
                for (int j = 0; j < innerContent.size(); ++j) {
                    JSONObject eqNode = innerContent.getJSONObject(j);
                    String eqCode = eqNode.get("code").toString();
//                    if(eqCode.length()==6){//是部件
//                        familyMap.put(familyCode,false);
//                    }
                    eqToFamilyMap.put(eqCode, familyCode);
                }
            }
        } catch (Exception e) {
            log.error("",e);
        }finally {
        }
    }

    private String dictId;

    public EqStaticInfo(String pjId){
        if(pjId == null){
            return;
        }
        if(!pjId.startsWith("Pj")){
            pjId = "Pj" + pjId;
        }
        this.init(pjId, false);
    }

    public EqStaticInfo(String dictId, boolean isDictId){
        this.init(dictId, true);
    }


    private void init(String id, boolean isDictId) {
        try {
            if(!isDictId) {
                this.dictId = TypeToInfosMap.getDictId(id);
            }else {
                this.dictId = id;
            }
            if(this.dictId == null){
                return;
            }

            Map<String, String> code2Parent = new HashMap<>();
            JSONObject cri = new JSONObject().fluentPut(CtmNodeTable.KEY_DICT_ID, dictId);
            JSONArray arr = CommonUtil.query(false, HBaseTable.ctm_node, cri).getJSONArray("Content");
            this.ctmNodeArr = arr;
            arr.forEach(o -> {
                JSONObject node = (JSONObject)o;
                if(!node.getString(CtmNodeTable.KEY_TYPE).equalsIgnoreCase("eq")){
                    this.dCateToNameMap.put(node.getString(CtmNodeTable.KEY_CODE), node.getString(CtmNodeTable.COL_NAME));
                    this.dFamilySet.add(node.getString(CtmNodeTable.KEY_CODE));
                    return;
                }

                //专业节点
                if(node.get("parent") == null){
                    this.dMajorCodeToNameMap.put(node.getString(CtmNodeTable.KEY_CODE), node.getString(CtmNodeTable.COL_NAME));
                    return;
                }

                //系统节点
                if(node.getString("code").length() == 2){
                    this.dSysSet.add(node.getString(CtmNodeTable.KEY_CODE));
                    this.dCateToNameMap.put(node.getString(CtmNodeTable.KEY_CODE), node.getString(CtmNodeTable.COL_NAME));
                    this.dCateToMajorMap.put(node.getString(CtmNodeTable.KEY_CODE),node.getString(CtmNodeTable.COL_PARENT));
                    return;
                }
                code2Parent.put(node.getString(CtmNodeTable.KEY_CODE),node.getString(CtmNodeTable.COL_PARENT));
                //设备节点
                if(node.getString("code").length() == 4){
                    this.dEqSet.add(node.getString(CtmNodeTable.KEY_CODE));
                    this.dEqToFamilyMap.put(node.getString(CtmNodeTable.KEY_CODE), node.getString(CtmNodeTable.COL_FAMILY));
                    this.dCateToNameMap.put(node.getString(CtmNodeTable.KEY_CODE), node.getString(CtmNodeTable.COL_NAME));
                    return;
                }
                //部件节点
                if(node.getString("code").length() == 6){
                    this.dEcSet.add(node.getString(CtmNodeTable.KEY_CODE));
                    this.dEqToFamilyMap.put(node.getString(CtmNodeTable.KEY_CODE), node.getString(CtmNodeTable.COL_FAMILY));
                    this.dCateToNameMap.put(node.getString(CtmNodeTable.KEY_CODE), node.getString(CtmNodeTable.COL_NAME));
                    return;
                }
            });
            code2Parent.forEach((k, v) -> {
                if(k.length() == 4){
                    this.dCateToMajorMap.put(k, this.dCateToMajorMap.get(v));
                }
            });
            code2Parent.forEach((k, v) -> {
                if(k.length() == 6){
                    this.dCateToMajorMap.put(k, this.dCateToMajorMap.get(v));
                }
            });
            this.dCateToMajorMap.forEach((k, v) -> {
                if(k.length() == 2){
                    if(this.dMajorToSysMap.get(v) == null){
                        this.dMajorToSysMap.put(v, new HashSet<>());
                    }
                    this.dMajorToSysMap.get(v).add(k);
                }
                if(k.length() == 4){
                    if(this.dMajorToEqMap.get(v) == null){
                        this.dMajorToEqMap.put(v, new HashSet<>());
                    }
                    this.dMajorToEqMap.get(v).add(k);
                }
            });
        } catch (Exception e) {
            log.error("",e);
        }
    }

    public Set<String> getSysSet() {
        if(this.dictId != null){
            return this.dSysSet;
        }
        return sysSet;
    }

    public Set<String> getEqSet() {
        if(this.dictId != null){
            return this.dEqSet;
        }
        return eqSet;
    }

    public Set<String> getEcSet() {
        if(this.dictId != null){
            return this.dEcSet;
        }
        return ecSet;
    }

    public Set<String> getFamilySet() {
        if(this.dictId != null){
            return this.dFamilySet;
        }
        return familySet;
    }

    public Map<String, String> getCateToMajorMap() {
        if(this.dictId != null){
            return this.dCateToMajorMap;
        }
        return cateToMajorMap;
    }

    public Map<String, String> getCateToNameMap() {
        if(this.dictId != null){
            return this.dCateToNameMap;
        }
        return cateToNameMap;
    }

    public Map<String, String> getMajorCodeToNameMap() {
        if(this.dictId != null){
            return this.dMajorCodeToNameMap;
        }
        return majorCodeToNameMap;
    }

    public Map<String, String> getEqToFamilyMap() {
        if(this.dictId != null){
            return this.dEqToFamilyMap;
        }
        return eqToFamilyMap;
    }

    public Map<String, Set<String>> getMajorToSysMap() {
        if(this.dictId != null){
            return this.dMajorToSysMap;
        }
        return majorToSysMap;
    }

    public Map<String, Set<String>> getMajorToEqMap() {
        if(this.dictId != null){
            return  this.dMajorToEqMap;
        }
        return majorToEqMap;
    }

    public String getDictId() {
        return dictId;
    }

    public JSONArray getCtmNodeArr() {
        return ctmNodeArr;
    }
}
