package com.sagacloud.endpointService;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sagacloud.endpointService.pojo.CalendarRule;
import com.sagacloud.utils.CommonUtil;
import com.sagacloud.utils.DpUtils;
import com.sagacloud.utils.tables.CalendarDescTable;
import com.sagacloud.utils.tables.CalendarRuleTable;
import com.sagacloud.utils.tables.CalendarTable;
import com.sagacloud.utils.tables.HBaseTable;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * Created by wo on 7/8/19.
 */
public class CalendarService {

    /**批量创建规则
     * @param jsonStr
     * @return
     * @throws Exception
     */
    public String createRules(String jsonStr) throws Exception {
        JSONArray arr = JSONObject.parseObject(jsonStr).getJSONArray("rules");
        Set<String> ids = new HashSet<>();
        JSONArray errs = new JSONArray();
        String[] types = {"dOfW", "dOfM", "mAndD"};
        for(int i = 0; i < arr.size(); i++){
            JSONObject item = arr.getJSONObject(i);
            ids.add(item.getString(CalendarRuleTable.KEY_ID));
            if(!item.containsKey(CalendarRuleTable.COL_VALUE)){
                item.put("error", "缺少" + CalendarRuleTable.COL_VALUE);
                errs.add(item);
                continue;
            }else{
                item.put(CalendarRuleTable.COL_VALUE,item.getString(CalendarRuleTable.COL_VALUE));
            }
            if(!item.containsKey(CalendarRuleTable.COL_TYPE)){
                item.put("error", "缺少" + CalendarRuleTable.COL_TYPE);
                errs.add(item);
                continue;
            }
            if(!Arrays.asList(types).contains(item.getString(CalendarRuleTable.COL_TYPE))){
                item.put("error", CalendarRuleTable.COL_TYPE + "值不合法");
                errs.add(item);
            }
        }
        if(errs.size() != 0){
            return  DpUtils.errorJson("").fluentPut("Error", errs).toString();
        }
        for(String id : ids){
            if(!this.isCalExist(id)){
                return DpUtils.errorJsonMsg(id + " 不存在！");
            }
        }
        return CommonUtil.insert(true, HBaseTable.calendar_rule, arr).toString();
    }

    /**批量删除规则
     * @param jsonStr
     * @return
     * @throws Exception
     */
    public String delRules(String jsonStr) throws Exception {
        JSONArray arr = JSONObject.parseObject(jsonStr).getJSONArray("rules");
        return CommonUtil.delete(true, HBaseTable.calendar_rule, arr).toString();
    }

    /**修改规则
     * @param jsonStr
     * @return
     * @throws Exception
     */
    public  String updateRule(String jsonStr) throws Exception {
        JSONObject upJson = JSONObject.parseObject(jsonStr);
        JSONObject cri = new JSONObject().fluentPut(CalendarRuleTable.KEY_ID, upJson.getString(CalendarRuleTable.KEY_ID))
                .fluentPut(CalendarRuleTable.KEY_TAG, upJson.getString(CalendarRuleTable.KEY_TAG));
        CommonUtil.update(false, HBaseTable.calendar_rule, cri, upJson.fluentRemove(CalendarRuleTable.KEY_ID).fluentRemove(CalendarRuleTable.KEY_TAG)
                .fluentPut(CalendarRuleTable.COL_VALUE, upJson.getString(CalendarRuleTable.COL_VALUE)));
        return DpUtils.successJsonMsg("");
    }

    /**查询规则
     * @return
     * @throws Exception
     */
    public  String queryRules(String jsonStr) throws Exception {
        JSONObject cri = JSONObject.parseObject(jsonStr);
        JSONObject re = CommonUtil.query(false, HBaseTable.calendar_rule, cri);
        re.getJSONArray("Content").forEach(o -> {
            JSONObject item = (JSONObject)o;
            item.put(CalendarRuleTable.COL_VALUE, item.getJSONArray(CalendarRuleTable.COL_VALUE));
        });
        return re.toString();
    }

    /**增加一套工作历
     * @param jsonStr
     * @return
     * @throws Exception
     */
    public  String create(String jsonStr) throws Exception {
        JSONObject insertJson = JSONObject.parseObject(jsonStr);
        String id = UUID.randomUUID().toString().replace("-", "");
        insertJson.put(CalendarDescTable.KEY_ID, id);
        CommonUtil.insert(false, HBaseTable.calendar_desc, insertJson);
        return DpUtils.successJsonMsgWithId("", id, null, null);
    }

    /**从已有工作历创建
     * @param jsonStr
     * @return
     * @throws Exception
     */
    public  String createFrom(String jsonStr) throws Exception {
        JSONObject insertJson = JSONObject.parseObject(jsonStr);
        String fromId = insertJson.getString("from_id");
        if(!this.isCalExist(fromId)){
            return DpUtils.errorJsonMsg(fromId + " 不存在！");
        }
        String id = UUID.randomUUID().toString().replace("-", "");
        insertJson.put(CalendarDescTable.KEY_ID, id);
        CommonUtil.insert(false, HBaseTable.calendar_desc, insertJson.fluentRemove("from_id"));
        JSONObject cri = new JSONObject().fluentPut(CalendarTable.KEY_ID, fromId);
        JSONObject reJson = CommonUtil.query(false, HBaseTable.calendar, cri);
        JSONArray contents = reJson.getJSONArray("Content");
        contents.forEach(o -> ((JSONObject)o).put(CalendarTable.KEY_ID, id));
        CommonUtil.insert(true, HBaseTable.calendar, contents);

        reJson = CommonUtil.query(false, HBaseTable.calendar_rule, cri);
        contents = reJson.getJSONArray("Content");
        contents.forEach(o -> ((JSONObject)o).put(CalendarTable.KEY_ID, id));
        CommonUtil.insert(true, HBaseTable.calendar_rule, contents);

        return DpUtils.successJsonMsgWithId("", id, null, null);
    }

    /**修改工作历
     * @param jsonStr
     * @return
     * @throws Exception
     */
    public  String update(String jsonStr) throws Exception {
        JSONObject upJson = JSONObject.parseObject(jsonStr);
        JSONObject cri = new JSONObject().fluentPut(CalendarDescTable.KEY_ID, upJson.getString(CalendarDescTable.KEY_ID));
        CommonUtil.update(false, HBaseTable.calendar_desc, cri, upJson.fluentRemove(CalendarDescTable.KEY_ID));
        return DpUtils.successJsonMsg("");
    }

    /**删除工作历
     * @param jsonStr
     * @return
     * @throws Exception
     */
    public  String del(String jsonStr) throws Exception {
        JSONObject delJson = JSONObject.parseObject(jsonStr);
        CommonUtil.delete(false, HBaseTable.calendar, delJson);
        CommonUtil.delete(false, HBaseTable.calendar_desc, delJson);
        return DpUtils.successJsonMsg("");
    }

    /**查询所有工作历
     * @return
     * @throws Exception
     */
    public  String query() throws Exception {
        JSONObject cri = new JSONObject();
        return CommonUtil.query(false, HBaseTable.calendar_desc, cri).toString();
    }

    /**工作历是否存在
     * @param id
     * @return
     * @throws Exception
     */
    public boolean isCalExist(String id) throws Exception {
        JSONObject cri = new JSONObject();
        cri.put(CalendarDescTable.KEY_ID, id);
        if(CommonUtil.query(false, HBaseTable.calendar_desc, cri).getInteger("Count") == 1){
            return true;
        }
        return false;
    }

    /**
     * @param id 工作历id
     * @param jo {"tag":"WorkDay-0","dates":[{"from":"20190707000000","to":"20190719000000"},{"from":"20190807000000","to":"20190819000000"}]}
     * @param isSet  true 为 set， false 为 unset
     */
    private void tag(boolean isSet, String id, JSONObject jo) throws Exception {
        String tag = jo.getString("tag");
        JSONArray insertTags = new JSONArray();
        insertTags.add(tag);
        String tmpStr = "{\"id\":\"%s\",\"date\":{\"$gte\":\"%s\",\"$lte\":\"%s\"}}";
        JSONArray cris = new JSONArray();
        JSONArray arr = jo.getJSONArray("dates");
        for(int i = 0; i < arr.size(); i++){
            JSONObject period = arr.getJSONObject(i);
            cris.add(JSONObject.parse(String.format(tmpStr, id, period.getString("from"), period.getString("to"))));
        }
        JSONArray contents = CommonUtil.combine_query(HBaseTable.calendar, cris).getJSONArray("Content");
        Map<String, JSONObject> map = new HashMap<>();
        for(int j = 0; j < contents.size(); j++){
            JSONObject entry = contents.getJSONObject(j);
            map.put(entry.getString(CalendarTable.KEY_DATE), entry);
        }

        JSONArray insertObjs = new JSONArray();
        JSONArray updateCris = new JSONArray();
        JSONArray sets = new JSONArray();

        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String upsertTmpStr = "{\"id\":\"%s\",\"date\":\"%s\"}";
        for(int k = 0; k < arr.size(); k++){
            JSONObject period = arr.getJSONObject(k);
            LocalDateTime from = LocalDateTime.parse(period.getString("from"), format).withHour(0).withMinute(0).withSecond(0);
            LocalDateTime to = LocalDateTime.parse(period.getString("to"), format).withHour(0).withMinute(0).withSecond(0).plusDays(1);
            while(from.isBefore(to)){
                JSONObject keyObj = JSONObject.parseObject(String.format(upsertTmpStr, id, from.format(format)));
                JSONObject record = map.get(from.format(format));
                if(record == null){
                    keyObj.put(CalendarTable.COL_TAGS, insertTags.toString());
                    insertObjs.add(keyObj);
                }else{
                    JSONArray updateTags;
                    JSONObject set = new JSONObject();
                    if(isSet){
                        if(record.get(CalendarTable.COL_TAGS) == null){
                            updateCris.add(keyObj);
                            updateTags = insertTags;
                            set.put(CalendarTable.COL_TAGS, updateTags.toString());
                            sets.add(set);
                        }else {
                            updateTags = JSONArray.parseArray(record.getString(CalendarTable.COL_TAGS));
                            for(int i = 0; i < updateTags.size(); i++){
                                String strTag = updateTags.getString(i);
                                if(strTag.startsWith(tag.split("-")[0])){
                                    updateTags.remove(strTag);
                                    break;
                                }
                            }
                            updateTags.add(tag);
                            updateCris.add(keyObj);
                            set.put(CalendarTable.COL_TAGS, updateTags.toString());
                            sets.add(set);


                        }

                    }else{
                        if(record.get(CalendarTable.COL_TAGS) != null){
                            updateTags = JSONArray.parseArray(record.getString(CalendarTable.COL_TAGS));
                            if(updateTags.contains(tag)){
                                updateCris.add(keyObj);
                                updateTags.remove(tag);
                                set.put(CalendarTable.COL_TAGS, updateTags.toString());
                                sets.add(set);
                            }
                        }
                    }

                }
                from = from.plusDays(1);
            }
        }
        if(insertObjs.size() > 0 && isSet){
            CommonUtil.insert(true, HBaseTable.calendar, insertObjs);
        }
        if(updateCris.size() > 0){
            CommonUtil.update(true, HBaseTable.calendar, updateCris, sets);
        }
    }

    /**
     * @param jsonStr 格式见接口文档 calendar/set_tags
     * @return
     * @throws Exception
     */
    public String setTags(String jsonStr) throws Exception {
        JSONObject json = JSONObject.parseObject(jsonStr);
        String id = json.getString("id");
        if(!this.isCalExist(id)){
            return DpUtils.errorJsonMsg("id不存在！");
        }
        JSONArray tags = json.getJSONArray("tags");
        for(int i = 0; i < tags.size(); i++){
            this.tag(true, id, tags.getJSONObject(i));
        }
        return DpUtils.successJsonMsg("");
    }

    /**
     * @param jsonStr 格式见接口文档 calendar/set_tags
     * @return
     * @throws Exception
     */
    public String unsetTags(String jsonStr) throws Exception {
        JSONObject json = JSONObject.parseObject(jsonStr);
        String id = json.getString("id");
        if(!this.isCalExist(id)){
            return DpUtils.errorJsonMsg("id不存在！");
        }
        JSONArray tags = json.getJSONArray("tags");
        for(int i = 0; i < tags.size(); i++){
            this.tag(false, id, tags.getJSONObject(i));
        }
        return DpUtils.successJsonMsg("");
    }

    /**
     * @param isSet true 为 set， false 为 unset
     * @param id
     * @param jo {"code":"OpenTime","time":["08:00-10:00","14:00-18:00"],"dates":[{"from":"20190707000000","to":"20190719000000"},{"from":"20190807000000","to":"20190819000000"}]}
     */
    private void interval(boolean isSet, String id, JSONObject jo) throws Exception {
        String code = jo.getString("code");
        JSONArray insertItvs = new JSONArray();
        String tmpStr = "{\"id\":\"%s\",\"date\":{\"$gte\":\"%s\",\"$lte\":\"%s\"}}";
        JSONArray cris = new JSONArray();
        JSONArray arr = jo.getJSONArray("dates");
        jo.remove("dates");
        insertItvs.add(jo);

        for(int i = 0; i < arr.size(); i++){
            JSONObject period = arr.getJSONObject(i);
            cris.add(JSONObject.parseObject(String.format(tmpStr, id, period.getString("from"), period.getString("to"))));
        }
        JSONArray contents = CommonUtil.combine_query(HBaseTable.calendar, cris).getJSONArray("Content");
        Map<String, JSONObject> map = new HashMap<>();
        for(int j = 0; j < contents.size(); j++){
            JSONObject entry = contents.getJSONObject(j);
            map.put(entry.getString(CalendarTable.KEY_DATE), entry);
        }

        JSONArray insertObjs = new JSONArray();
        JSONArray updateCris = new JSONArray();
        JSONArray sets = new JSONArray();

        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String upsertTmpStr = "{\"id\":\"%s\",\"date\":\"%s\"}";
        for(int k = 0; k < arr.size(); k++){
            JSONObject period = arr.getJSONObject(k);
            LocalDateTime from = LocalDateTime.parse(period.getString("from"), format).withHour(0).withMinute(0).withSecond(0);
            LocalDateTime to = LocalDateTime.parse(period.getString("to"), format).withHour(0).withMinute(0).withSecond(0).plusDays(1);
            while(from.isBefore(to)){
                JSONObject keyObj = JSONObject.parseObject(String.format(upsertTmpStr, id, from.format(format)));
                JSONObject record = map.get(from.format(format));
                if(record == null){
                    keyObj.put(CalendarTable.COL_INTERVALS, insertItvs.toString());
                    insertObjs.add(keyObj);
                }else{
                    JSONArray updateItvs;
                    JSONObject set = new JSONObject();
                    if(isSet){
                        updateCris.add(keyObj);
                        if(record.get(CalendarTable.COL_INTERVALS) == null){
                            updateItvs = insertItvs;
                        }else {
                            updateItvs = JSONArray.parseArray(record.getString(CalendarTable.COL_INTERVALS));
                            this.delItv(updateItvs, code);
                            updateItvs.add(jo);
                        }
                        set.put(CalendarTable.COL_INTERVALS, updateItvs.toString());
                        sets.add(set);
                    }else{
                        if(record.get(CalendarTable.COL_INTERVALS) != null){
                            updateItvs = JSONArray.parseArray(record.getString(CalendarTable.COL_INTERVALS));
                            if(this.isContainItv(updateItvs, code)){
                                updateCris.add(keyObj);
                                this.delItv(updateItvs, code);
                                set.put(CalendarTable.COL_INTERVALS, updateItvs.toString());
                                sets.add(set);
                            }
                        }
                    }

                }
                from = from.plusDays(1);
            }
        }
        if(insertObjs.size() > 0 && isSet){
            CommonUtil.insert(true, HBaseTable.calendar, insertObjs);
        }
        if(updateCris.size() > 0){
            CommonUtil.update(true, HBaseTable.calendar, updateCris, sets);
        }
    }

    /**
     * @param itvs  [{"code":"OpenTime","time":["08:00-10:00","14:00-18:00"]},{"code":"CoolTime","time":["09:00-11:00","16:00-18:00"]}]
     * @param code
     */
    private void delItv(JSONArray itvs, String code){
        for(int i = 0; i < itvs.size(); i++){
            JSONObject entry = itvs.getJSONObject(i);
            if(entry.getString("code").equalsIgnoreCase(code)){
                itvs.remove(entry);
                return;
            }
        }
    }

    /**
     * @param itvs  [{"code":"OpenTime","time":["08:00-10:00","14:00-18:00"]},{"code":"CoolTime","time":["09:00-11:00","16:00-18:00"]}]
     * @param code
     */
    private boolean isContainItv(JSONArray itvs, String code){
        for(int i = 0; i < itvs.size(); i++){
            JSONObject entry = itvs.getJSONObject(i);
            if(entry.getString("code").equalsIgnoreCase(code)){
                return true;
            }
        }
        return false;
    }

    /**
     * @param jsonStr 格式见接口文档 calendar/set_intervals
     * @return
     * @throws Exception
     */
    public String setItvs(String jsonStr) throws Exception {
        JSONObject json = JSONObject.parseObject(jsonStr);
        String id = json.getString("id");
        if(!this.isCalExist(id)){
            return DpUtils.errorJsonMsg("id不存在！");
        }
        JSONArray intervals = json.getJSONArray("intervals");
        for(int i = 0; i < intervals.size(); i++){
            this.interval(true, id, intervals.getJSONObject(i));
        }
        return DpUtils.successJsonMsg("");
    }

    /**
     * @param jsonStr 格式见接口文档 calendar/set_intervals
     * @return
     * @throws Exception
     */
    public String unsetItvs(String jsonStr) throws Exception {
        JSONObject json = JSONObject.parseObject(jsonStr);
        String id = json.getString("id");
        if(!this.isCalExist(id)){
            return DpUtils.errorJsonMsg("id不存在！");
        }
        JSONArray intervals = json.getJSONArray("intervals");
        for(int i = 0; i < intervals.size(); i++){
            this.interval(false, id, intervals.getJSONObject(i));
        }
        return DpUtils.successJsonMsg("");
    }

    /**
     * @param src ["WorkDay-0", "ACSeason-1", "OpenDay-1"]
     * @param def ["WorkDay", "ACSeason"]
     */
    private void rmTag(JSONArray src, JSONArray def){
        for(String tag : src.toJavaList(String.class)){
            boolean rmFlag = true;
            for(int k = 0; k < def.size(); k++){
                if(tag.startsWith(def.getString(k))){
                    rmFlag = false;
                    break;
                }
            }
            if(rmFlag){
                src.remove(tag);
            }
        }
    }

    /**
     * @param jsonStr {"id":"2c53d807b27946e19b3fdc935418ea9b","tag":["WorkDay","ACSeason"],"code":["OpenTime","CoolTime"],"dates":{"from":"20190707000000","to":"20190719000000"}}
     * @return
     */
    public String queryDetails(String jsonStr) throws Exception {
        JSONObject json = JSONObject.parseObject(jsonStr);
        String id = json.getString("id");
        String tmpStr = "{\"id\":\"%s\",\"date\":{\"$gte\":\"%s\",\"$lte\":\"%s\"}}";
        JSONObject period = json.getJSONObject("dates");
        JSONObject cri = JSONObject.parseObject(String.format(tmpStr, id, period.getString("from"), period.getString("to")));
        JSONObject reJson = CommonUtil.query(false, HBaseTable.calendar, cri);
        JSONArray contents = reJson.getJSONArray("Content");
        JSONArray itvs = null;
        JSONArray tags = null;
        if(json.get("tags") != null){
            tags = json.getJSONArray("tags");
        }
        if(json.get("intervals") != null){
            itvs = json.getJSONArray("intervals");
        }
        List<JSONObject> toDels = new ArrayList<>();
        for (int i = 0; i < contents.size(); i++){
            JSONObject date = contents.getJSONObject(i);
            //移除那些都为空的记录
            if((date.get(CalendarTable.COL_TAGS) == null || date.getJSONArray(CalendarTable.COL_TAGS).size() == 0)
                    && (date.get(CalendarTable.COL_INTERVALS) == null || date.getJSONArray(CalendarTable.COL_INTERVALS).size() == 0)){
                toDels.add(date);
                continue;
            }

            if(tags == null){
                date.remove(CalendarTable.COL_TAGS);
            }else if(tags.size() != 0){
                if(date.get(CalendarTable.COL_TAGS) == null){
                    date.put(CalendarTable.COL_TAGS, new JSONArray());
                }else{
                    JSONArray tagArr = date.getJSONArray(CalendarTable.COL_TAGS);
                    this.rmTag(tagArr, tags);
                    date.put(CalendarTable.COL_TAGS, tagArr);
                }

            }else{
                if(date.get(CalendarTable.COL_TAGS) == null){
                    date.put(CalendarTable.COL_TAGS, new JSONArray());
                }else{
                    JSONArray tagArr = date.getJSONArray(CalendarTable.COL_TAGS);
                    date.put(CalendarTable.COL_TAGS, tagArr);
                }
            }

            if(itvs == null){
                date.remove(CalendarTable.COL_INTERVALS);
            }else if(itvs.size() != 0){
                if(date.get(CalendarTable.COL_INTERVALS) == null){
                    date.put(CalendarTable.COL_INTERVALS, new JSONArray());
                }else{
                    JSONArray itvArr = date.getJSONArray(CalendarTable.COL_INTERVALS);
                    for(JSONObject itv : itvArr.toJavaList(JSONObject.class)) {
                        if (!itvs.contains(itv.getString("code"))){
                            itvArr.remove(itv);
                        }
                    }
                    date.put(CalendarTable.COL_INTERVALS, itvArr);
                }
            }else{
                if(date.get(CalendarTable.COL_INTERVALS) == null){
                    date.put(CalendarTable.COL_INTERVALS, new JSONArray());
                }else{
                    JSONArray itvArr = date.getJSONArray(CalendarTable.COL_INTERVALS);
                    date.put(CalendarTable.COL_INTERVALS, itvArr);
                }
            }
        }
        this.delCals(toDels);
        toDels.forEach(jsonObject -> contents.remove(jsonObject));
        //根据规则添加内容
        if(tags != null){
            Map<String, List<String>> d2tags = this.generateFromRule(id, period.getString("from"), period.getString("to"), tags.toJavaList(String.class));
            List<JSONObject> objs = new ArrayList<>();
            for(int i = 0; i < contents.size(); i++){
                JSONObject item = contents.getJSONObject(i);
                String dateStr = item.getString("date");
                if(!d2tags.containsKey(dateStr)){
                    objs.add(item);
                    continue;
                }
                List<String> tagLst = d2tags.get(dateStr);
                d2tags.remove(dateStr);
                item.put("tags", this.combineTags(tagLst, item.containsKey("tags")? item.getJSONArray("tags"): null));
                objs.add(item);
            }
            d2tags.forEach(((k, v) -> objs.add(new JSONObject().fluentPut("date", k).fluentPut("tags", v))));
            objs.sort(((o1, o2) -> o1.getString("date").compareTo(o2.getString("date"))));
            contents.clear();
            objs.forEach(item -> contents.add(item));
        }

        this.postHandleCals(contents);
        reJson.put("Content", contents);
        reJson.put("Count", contents.size());
        return reJson.toString();
    }

    /**合并规则中的tag到原结果
     * @param ruleTags
     * @param arr
     * @return
     */
    private List<String> combineTags(List<String> ruleTags, JSONArray arr){
        if(arr == null || arr.size() == 0){
            return ruleTags;
        }
        List<String> reList = arr.toJavaList(String.class);
        for(String tag : ruleTags){
            if(reList.contains(tag)){
                continue;
            }
            String prefix = tag.split("-")[0];
            boolean isExisted = false;
            for(String reTag : reList){
                if(reTag.startsWith(prefix)){
                    isExisted = true;
                    break;
                }
            }
            if(!isExisted){
                reList.add(tag);
            }
        }
        return reList;
    }

    private boolean isContained(List<String> tags, String tag){
        String prefix = tag.split("-")[0];
        for(String t : tags){
           if(t.startsWith(prefix)){
               return true;
           }
        }
        return false;
    }

    /**根据规则生成按天返回tags
     * @param id 字典id
     * @param fromStr 开始日期
     * @param toStr  结束日期
     * @param tags tags
     * @return 工作历详情
     */
    private Map<String, List<String>> generateFromRule(String id, String fromStr, String toStr, List<String> tags) throws Exception {
        JSONObject re = CommonUtil.query(false, HBaseTable.calendar_rule, new JSONObject().fluentPut(CalendarRuleTable.KEY_ID, id));
        List<CalendarRule> rules = new ArrayList<>();
        re.getJSONArray("Content").forEach(o -> {
            JSONObject item = (JSONObject)o;
            if(!tags.isEmpty() && !this.isContained(tags, item.getString(CalendarRuleTable.KEY_TAG))){
                return;
            }
            rules.add(new CalendarRule(item.getString(CalendarRuleTable.KEY_TAG), item.getString(CalendarRuleTable.COL_TYPE), item.getJSONArray(CalendarRuleTable.COL_VALUE)));
        });
        Map<String, List<String>> map = new HashMap<>();
        if(rules.isEmpty()){
            return  map;
        }
        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime from = LocalDateTime.parse(fromStr, format).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime to = LocalDateTime.parse(toStr, format).withHour(0).withMinute(0).withSecond(0);
        while(!from.isAfter(to)){
            List<String> tagLst = new ArrayList<>();
            for(CalendarRule rule : rules){
                if(rule.isMatching(from)){
                    tagLst.add(rule.getTag());
                }
            }
            if(!tagLst.isEmpty()){
                map.put(from.format(format), tagLst);
            }
            from = from.plusDays(1);
        }
        return map;
    }

    /**处理queryDetails的最后查询结构，删除那些空的记录
     * @param contents
     */
    private void postHandleCals(JSONArray contents){
        List<JSONObject> toDels = new ArrayList<>();
        contents.forEach(o -> {
            JSONObject entry = (JSONObject)o;
            entry.remove(CalendarTable.KEY_ID);
            //移除那些都为空的记录
            if((entry.get(CalendarTable.COL_TAGS) == null || entry.getJSONArray(CalendarTable.COL_TAGS).size() == 0)
                    && (entry.get(CalendarTable.COL_INTERVALS) == null || entry.getJSONArray(CalendarTable.COL_INTERVALS).size() == 0)){
                toDels.add(entry);
            }
        });
        toDels.forEach(jsonObject -> contents.remove(jsonObject));
    }

    /**删除工作历条目
     * @param toDels
     * @throws Exception
     */
    private void delCals(List<JSONObject> toDels) throws Exception {
        if(toDels.isEmpty()){
            return;
        }
        JSONArray cris = new JSONArray();
        toDels.forEach(o -> {
            JSONObject jo = new JSONObject();
            jo.put(CalendarTable.KEY_ID, o.get(CalendarTable.KEY_ID));
            jo.put(CalendarTable.KEY_DATE, o.get(CalendarTable.KEY_DATE));
            cris.add(jo);
        });
        CommonUtil.combine_delete(HBaseTable.calendar, cris);
    }
}
