package com.sagacloud.utils.objectLog;
/*
 * Author: Jxing
 * Create Time: 2017/10/14
 */

import com.google.common.base.Strings;
import com.sagacloud.broadcast.MessageHandler;
//import com.sagacloud.json.JSONArray;
//import com.sagacloud.json.JSONObject;
//import com.sagacloud.json.JSONValue;
import com.alibaba.fastjson.*;
import com.sagacloud.utils.*;
import com.sagacloud.utils.objects.MQType;
import com.sagacloud.utils.objects.ObjectType;
import com.sagacloud.utils.tables.ActivityLogTable;
import com.sagacloud.utils.tables.HBaseTable;
import com.sagacloud.utils.tables.ObjectTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ActivityLogUtil {
    private static final Logger log = LoggerFactory.getLogger(ActivityLogUtil.class);
    private static final String commonStr = "{\"QueryType\":\"insert\",\"Datatable\":\"activity_log\"}";
    private static final String batchInsertStr = "{\"QueryType\":\"batch_insert\",\"Datatable\":\"activity_log\"}";
    public static ExecutorService pool = Executors.newFixedThreadPool(16);

    public static void objectLog(String id, String time, ObjectType ot, MQType type) throws Exception {
        JSONObject id_json = new JSONObject();
        id_json.put("id", id);
        DpUtils.rewriteCriteria(id_json, "id", true);
        Object obj_idValue = id_json.get(ObjectTable.KEY_OBJ_ID);
        if (id_json.get(ObjectTable.KEY_OBJ_ID) != null && id_json.get(ObjectTable.KEY_OBJ_ID).equals("")) {
            obj_idValue = null;
        }
        JSONObject mq = new JSONObject();
        mq.put("type", getSequenceNO(type));
        mq.put("name", type.name());
        JSONObject insertObject = new JSONObject();
        insertObject.put(ActivityLogTable.KEY_TIME, time);
        insertObject.put(ActivityLogTable.KEY_PJ_ID, id_json.get(ObjectTable.KEY_PJ_ID));
        insertObject.put(ActivityLogTable.KEY_OBJ_TYPE, id_json.get(ObjectTable.KEY_OBJ_TYPE));
        insertObject.put(ActivityLogTable.KEY_OBJ_ID, obj_idValue);
        insertObject.put(ActivityLogTable.KEY_INFO_ID, null);
        String note = getNote(ot, type);
        insertObject.put(ActivityLogTable.COL_INFO_NOTE, note);

        mq.put("projectId", "Pj" + id_json.get(ObjectTable.KEY_PJ_ID));
        mq.put("id", id);
        mq.put("time", time);
        mq.put("description", note == null ? "" : note);
        try {
            CommonUtil.insert(false, HBaseTable.activity_log, insertObject);
        } catch (Exception ex) {
            ActivityLogUtil.log.error("write to log failed:" + log.toString());
        }
        MessageHandler.publish(mq.toString());
    }

    public static void objectLog(String id, String time, ObjectType ot, MQType type, String pjId) throws Exception {
        JSONObject id_json = new JSONObject();
        id_json.put("id", id);
        DpUtils.rewriteCriteria(id_json, "id", true);
        Object obj_idValue = id_json.get(ObjectTable.KEY_OBJ_ID);
        if (id_json.get(ObjectTable.KEY_OBJ_ID) != null && id_json.get(ObjectTable.KEY_OBJ_ID).equals("")) {
            obj_idValue = null;
        }
        JSONObject mq = new JSONObject();
        mq.put("type", getSequenceNO(type));
        mq.put("name", type.name());
        JSONObject log = JSONObject.parseObject(commonStr);
        log.put("Database", OssUtils.getProperty("database.name"));
        JSONObject insertObject = new JSONObject();
        log.put(Const.JSON_FIELD_INSERTOBJECT, insertObject);
        insertObject.put(ActivityLogTable.KEY_TIME, time);
        insertObject.put(ActivityLogTable.KEY_PJ_ID, pjId);
        insertObject.put(ActivityLogTable.KEY_OBJ_TYPE, id_json.get(ObjectTable.KEY_OBJ_TYPE));
        insertObject.put(ActivityLogTable.KEY_OBJ_ID, obj_idValue);
        insertObject.put(ActivityLogTable.KEY_INFO_ID, null);
        String note = getNote(ot, type);
        insertObject.put(ActivityLogTable.COL_INFO_NOTE, note);

        mq.put("id", id);
        mq.put("time", time);
        mq.put("projectId", String.join("", "Pj", pjId));
        mq.put("description", note == null ? "" : note);
        try {
            ZillionAgentProvider.GetAgent().Query(log);
        } catch (Exception ex) {
            ActivityLogUtil.log.error("write to log failed:" + log.toString());
        }
        MessageHandler.publish(mq.toString());
    }

    private static String getNote(ObjectType ot, MQType mq) {
        StringBuilder sb = new StringBuilder();
//        switch (ot)
//        {
//            case equipment:
//                sb.append("设备");
//                break;
//            case system:
//                sb.append("系统");
//                break;
//            case floor:
//                sb.append("楼层");
//                break;
//            case space:
//                sb.append("空间");
//                break;
//            case VO:
//                sb.append("虚拟对象");
//                break;
//            case VOBd:
//                sb.append("虚拟楼层");
//                break;
//            case building:
//                sb.append("建筑");
//                break;
//        }
        switch (mq) {
            case objectCreate:
//                sb.append("创建");
                sb.append("新增一个对象实例");
                break;
            case objectDelete:
//                sb.append("删除");
                sb.append("作废一个对象实例");
                break;
            case realDelete:
//                sb.append("删除");
                sb.append("真删除一个对象实例");
                break;
        }
        return sb.toString();
    }

    public static void objectLog(String id, String time, String note, MQType type) throws Exception {
        JSONObject id_json = new JSONObject();
        id_json.put("id", id);
        DpUtils.rewriteCriteria(id_json, "id", true);
        Object obj_idValue = id_json.get(ObjectTable.KEY_OBJ_ID);
        if (id_json.get(ObjectTable.KEY_OBJ_ID) != null && id_json.get(ObjectTable.KEY_OBJ_ID).equals("")) {
            obj_idValue = null;
        }
        JSONObject mq = new JSONObject();
        mq.put("type", getSequenceNO(type));
        mq.put("name", type.name());
        JSONObject log = JSONObject.parseObject(commonStr);
        log.put("Database", OssUtils.getProperty("database.name"));
        JSONObject insertObject = new JSONObject();
        log.put(Const.JSON_FIELD_INSERTOBJECT, insertObject);
        insertObject.put(ActivityLogTable.KEY_TIME, time);
        insertObject.put(ActivityLogTable.KEY_PJ_ID, id_json.get(ObjectTable.KEY_PJ_ID));
        insertObject.put(ActivityLogTable.KEY_OBJ_TYPE, id_json.get(ObjectTable.KEY_OBJ_TYPE));
        insertObject.put(ActivityLogTable.KEY_OBJ_ID, obj_idValue);
        insertObject.put(ActivityLogTable.KEY_INFO_ID, null);
        insertObject.put(ActivityLogTable.COL_INFO_NOTE, note);

        mq.put("id", id);
        mq.put("time", time);
        mq.put("description", note == null ? "" : note);
        try {
            ZillionAgentProvider.GetAgent().Query(log);
        } catch (Exception ex) {
            ActivityLogUtil.log.error("write to log failed:" + log.toString());
        }
        MessageHandler.publish(mq.toString());
    }

    public static void objectInfoChange(String projectId, JSONArray jsonArray, MQType type, String operationTime) throws Exception {
        if (jsonArray.size() < 1)
            return;
        JSONObject mq = new JSONObject();
        mq.put("type", getSequenceNO(type));
        mq.put("name", type.name());
        mq.put("operation_time", operationTime);
        mq.put("projectId", CommonMethods.getProject(projectId, true));
        mq.put("infos", jsonArray);
        JSONObject log = JSONObject.parseObject(batchInsertStr);
        log.put("Database", OssUtils.getProperty("database.name"));
        JSONArray insertObjects = new JSONArray();
        log.put(Const.JSON_FIELD_INSERTOBJECTS, insertObjects);
        for (int i = 0; i < jsonArray.size(); ++i) {
            JSONObject single = (JSONObject) jsonArray.get(i);
//            CommonUtil.rewriteCriteria(single, "id");
            JSONObject insertObject = new JSONObject();
            insertObject.put(ActivityLogTable.KEY_TIME, operationTime);
            insertObject.put(ActivityLogTable.KEY_PJ_ID, CommonMethods.getProject(projectId, false));
            insertObject.put(ActivityLogTable.KEY_OBJ_TYPE, single.get(ObjectTable.KEY_OBJ_TYPE));
            insertObject.put(ActivityLogTable.KEY_OBJ_ID, single.get(ObjectTable.KEY_OBJ_ID) != null ?
                    (single.get(ObjectTable.KEY_OBJ_ID).equals("") ? null : single.get(ObjectTable.KEY_OBJ_ID)) : null);
            insertObject.put(ActivityLogTable.KEY_INFO_ID, single.get("info_id"));
            StringBuilder note = new StringBuilder();
            note.append(single.get("description").toString());
            note.append(single.get("time"));
            insertObject.put(ActivityLogTable.COL_INFO_NOTE, note.toString());
            insertObjects.add(insertObject);
            single.put("id", CommonUtil.combineId(Strings.nullToEmpty((String) single.get(ObjectTable.KEY_PJ_ID)),
                    Strings.nullToEmpty((String) single.get(ObjectTable.KEY_OBJ_TYPE)),
                    Strings.nullToEmpty((String) single.get(ObjectTable.KEY_OBJ_ID))));
            single.remove(ObjectTable.KEY_PJ_ID);
            single.remove(ObjectTable.KEY_OBJ_TYPE);
            single.remove(ObjectTable.KEY_OBJ_ID);
        }
        try {
            ZillionAgentProvider.GetAgent().Query(log);
        } catch (Exception ex) {
            ActivityLogUtil.log.error("write to log failed:" + log.toString());
        }
        MessageHandler.publish(mq.toString());
    }

    private static Long getSequenceNO(MQType type) {
        switch (type) {
            case objectCreate:
                return 1L;
            case objectDelete:
            case realDelete:
                return 2L;
            case infoValueChange:
                return 7L;
        }
        log.error("MQ type error!");
        return -1L;
    }


    public static void addMessageToQueue(String pjId, String time, ArrayList<ActivityLogObject> logList, String id,
                                         ObjectType ot) {
        ActivityLogObject logObj = new ActivityLogObject();
        logObj.setId(id);
        logObj.setTime(time);
        logObj.setOt(ot);
        logObj.setType(MQType.objectCreate);
        logObj.setProjectId(pjId);
        logList.add(logObj);
    }
}






















