package com.sagacloud.endpoints;


import com.sagacloud.json.JSONArray;
import com.sagacloud.json.JSONObject;
import com.sagacloud.json.JSONValue;
import com.sagacloud.utils.Const;
import com.sagacloud.utils.DpUtils;
import com.sagacloud.utils.OssUtils;
import com.sagacloud.utils.ZillionAgentProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * 租户保存历史数据用
 * Created on 2018/8/15.
 */
@Path("timedata")
public class InfoCodeTimeData {
    private static final Logger log = LoggerFactory.getLogger(InfoCodeTimeData.class);

    private final static String TIME_DATA_TABLE_NAME = "timedata_month";

    private final static String TABLE_FIELD_PROJECT = "project";
    private final static String TABLE_FIELD_OBJECT = "object";
    private final static String TABLE_FIELD_CODE = "code";
    private final static String TABLE_FIELD_TIME = "time";
    private final static String TABLE_FIELD_DATA = "data";

    private final static Set<String> tableFieldName = new HashSet<>();
    static {
        tableFieldName.add(TABLE_FIELD_OBJECT); tableFieldName.add(TABLE_FIELD_CODE);
        tableFieldName.add(TABLE_FIELD_TIME); tableFieldName.add(TABLE_FIELD_DATA);
    }

    @Path("/query_by_obj")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String select(String jsonStr) throws Exception {
        try {
            JSONObject json = (JSONObject) JSONValue.parse(jsonStr);
            if (!json.containsKey(Const.PROJECT_ID)) {
                return DpUtils.errorJsonMsg("缺少必要字段");
            }

            String projectId = (String) json.get(Const.PROJECT_ID);
            if (projectId == null) {
                return DpUtils.errorJsonMsg("projectId不能为空");
            }

            JSONObject criteria = (JSONObject) json.get("criteria");
         //   if (criteria.get(TABLE_FIELD_CODE) == null || criteria.get(TABLE_FIELD_TIME) == null)
        //        return DpUtils.errorJsonMsg("criteria中缺少必要字段");

            // String object = criteria.get(TABLE_FIELD_OBJECT).toString();
            /*String code = (String) CommonUtil.getInfoById(object, (String) criteria.get(TABLE_FIELD_CODE));
            if (code == null) {
                return DpUtils.errorJsonMsg("Assigned code does not exist");
            }*/

            log.info("Input: " + jsonStr);
            JSONObject queryObject = new JSONObject();
            queryObject.put("QueryType","select");
            String energyDatabase = OssUtils.getProperty("energy.database.name");
            queryObject.put("Database", energyDatabase);
            queryObject.put("Datatable", TIME_DATA_TABLE_NAME);
            criteria.put(TABLE_FIELD_PROJECT, projectId);
            queryObject.put("Criteria", criteria);
            log.info(queryObject.toString());
            return ZillionAgentProvider.GetAgent().Query(queryObject).toString();
        } catch (Exception ex) {
            return DpUtils.errorJsonMsg(Arrays.toString(ex.getStackTrace()));
        }
    }

    @Path("/batch_insert")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String bInsertOriginal(String jsonStr) {
        JSONObject json = (JSONObject) JSONValue.parse(jsonStr);
        if (!json.containsKey(Const.PROJECT_ID)) {
            return DpUtils.errorJsonMsg("缺少必要字段");
        }

        String projectId = (String) json.get(Const.PROJECT_ID);
        if (projectId == null) {
            return DpUtils.errorJsonMsg("projectId不能为空");
        }
        JSONArray jsonArray = (JSONArray) json.get("insertObjects");
        JSONArray insertObjects = new JSONArray();
        String errorMsg = "";
        for(int i = 0; i < jsonArray.size(); i++){
            JSONObject insertObject = (JSONObject) jsonArray.get(i);
            errorMsg = checkObjectInfo(insertObject);
            if(null != errorMsg) {
                return DpUtils.errorJsonMsg(errorMsg);
            }
            insertObject.put(TABLE_FIELD_PROJECT, projectId);
            insertObjects.add(insertObject);
        }

        if(insertObjects.size() == 0){
            return DpUtils.errorJsonMsg(errorMsg);
        }
        //   JSONObject exeJson = (JSONObject) JSONValue.parse(String.format("{\"QueryType\":\"batch_insert\",\"Database\":\"db_time_data\",\"Datatable\":\"%s\"}", table));

        JSONObject exeJson = new JSONObject();
        exeJson.put("QueryType","batch_insert");
        String energyDatabase = OssUtils.getProperty("energy.database.name");
        exeJson.put("Database",energyDatabase);
        exeJson.put("Datatable",TIME_DATA_TABLE_NAME);

        exeJson.put("InsertObjects", insertObjects);
        JSONObject re = null;
        try {
            log.info(exeJson.toString());
            re = ZillionAgentProvider.GetAgent().Query(exeJson);
            re.put("ResultMsg", errorMsg);
            return re.toString();
        } catch (Exception e) {
            log.error("",e);
            return DpUtils.errorJsonMsg(Arrays.toString(e.getStackTrace()));
        }
    }

    private String checkObjectInfo(JSONObject insertObject) {
        String error = null;

        if(insertObject.keySet() == null || tableFieldName.size() != insertObject.keySet().size()) {
            return "插入对象缺少必要字段";
        } else {
            for(String key : tableFieldName) {
                if(!insertObject.keySet().contains(key)) {
                    return "插入对象缺少必要" + key + "字段";
                }

                if(insertObject.get(key) == null) {
                    return "插入对象" + key + "字段值不能为空";
                }
            }
        }

        return error;
    }

    @Path("/batch_delete")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String delete(String jsonStr) {
        JSONObject jsonObject = (JSONObject) JSONValue.parse(jsonStr);
        if (!jsonObject.containsKey(Const.PROJECT_ID)) {
            return DpUtils.errorJsonMsg("缺少必要字段");
        }

        String projectId = (String) jsonObject.get(Const.PROJECT_ID);
        if (projectId == null) {
            return DpUtils.errorJsonMsg("projectId不能为空");
        }
        String[] requiredFields = {TABLE_FIELD_OBJECT, TABLE_FIELD_CODE, TABLE_FIELD_TIME};

        JSONArray jsonArray = (JSONArray) jsonObject.get("criterias");
        JSONArray deleteCriterias = new JSONArray();
        String errorMsg = "";

        for(int i = 0; i < jsonArray.size(); i++){
            JSONObject criteria = (JSONObject) jsonArray.get(i);
            JSONObject deleteCriteria = new JSONObject();
            try {
                for(int j = 0; j < requiredFields.length; j++){
                    if(criteria.get(requiredFields[j]) == null){
                        throw new Exception("Object in criterias Must contain " + requiredFields[j] + " and it's value");
                    }
                }
                deleteCriteria.put(TABLE_FIELD_PROJECT, projectId);
                deleteCriteria.put(TABLE_FIELD_OBJECT, criteria.get(TABLE_FIELD_OBJECT));
                deleteCriteria.put(TABLE_FIELD_CODE, criteria.get(TABLE_FIELD_CODE));
                deleteCriteria.put(TABLE_FIELD_TIME, criteria.get(TABLE_FIELD_TIME));
            } catch (Exception e) {
                errorMsg = String.join("##", criteria.toString() + " with error : " + e.getMessage());
                continue;
            }
            deleteCriterias.add(deleteCriteria);
        }

        if(deleteCriterias.size() == 0){
            return DpUtils.errorJsonMsg(errorMsg);
        }

        JSONObject exeJson = new JSONObject();
        exeJson.put("QueryType","batch_delete");
        String energyDatabase = OssUtils.getProperty("energy.database.name");
        exeJson.put("Database",energyDatabase);
        exeJson.put("Datatable",TIME_DATA_TABLE_NAME);

        exeJson.put("Criterias", deleteCriterias);
        JSONObject re = null;
        try {
            log.info(exeJson.toString());
            re = ZillionAgentProvider.GetAgent().Query(exeJson);
            re.put("ResultMsg", errorMsg);
            return re.toString();
        } catch (Exception e) {
            log.error("",e);
            return DpUtils.errorJsonMsg(Arrays.toString(e.getStackTrace()));
        }
    }
}
