package com.sagacloud.endpoints.mng;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.sagacloud.cache.ProPasCache;
import com.sagacloud.dict.EqStaticInfo;
import com.sagacloud.dict.GeoStaticInfo;
import com.sagacloud.dict.InfosUtil;
import com.sagacloud.exception.IdGenException;
import com.sagacloud.exception.WrongInfosException;
import com.sagacloud.utils.CommonUtil;
import com.sagacloud.utils.Const;
import com.sagacloud.utils.DpUtils;
import com.sagacloud.utils.ObjectUtil;
import com.sagacloud.utils.OssUtils;
import com.sagacloud.utils.ZillionAgentProvider;
import com.sagacloud.utils.objectLog.ActivityLogUtil;
import com.sagacloud.utils.objects.CommonQueryCriteria;
import com.sagacloud.utils.objects.MQType;
import com.sagacloud.utils.objects.ObjectIdName;
import com.sagacloud.utils.objects.ObjectType;
import com.sagacloud.utils.relationUtils.SubsetUtil;
import com.sagacloud.utils.tables.HBaseTable;
import com.sagacloud.utils.tables.ObjInfosTable;
import com.sagacloud.utils.tables.ProjectTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.Set;

//import com.sagacloud.json.JSONArray;
//import com.sagacloud.json.JSONObject;
//import com.sagacloud.json.JSONValue;

/**
 * Created by wushengzong on 2017/4/21.
 */
@Path("mng/project")
public class Project {
    private static final Logger log = LoggerFactory.getLogger(Project.class);
    //public final static String NAME = "project";
    @Path("/create")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String create(String jsonStr){
        /*String re = this.validateCreateJsonSchema(jsonStr);
        if(!re.isEmpty()){
            JSONObject jsonObj = (JSONObject) JSONValue.parse("{}");
            jsonObj.put("error", re);
            return jsonObj.toString();
        }*/


        JSONObject insertObjectNode = JSONObject.parseObject(jsonStr);
        JSONObject json = JSONObject.parseObject(Const.COMMON_JSON);
        json.put("Database", OssUtils.getProperty("database.name"));
        json.put(Const.FIELD_TABLE_NAME, Const.TABLE_PROJECT_NAME);
        String projectid = null;
        String areaCode = null;
        String id = "";
        /*if(Strings.nullToEmpty((String)insertObjectNode.get("password")).length()==0){
            return DpUtils.errorJsonMsg("password cannot be empty!");
        }*/
        // 指定id生成对象
        if(insertObjectNode.get("id") != null )
        {
            if(insertObjectNode.get("id").toString().length() == 12 && insertObjectNode.get("id").toString().startsWith("Pj")) {
                projectid = insertObjectNode.get("id").toString().substring(2);
                areaCode = projectid.substring(0, 6);
                id = projectid.substring(6);
                if (!DpUtils.verifyAssignedObjID(id)) {
                    return DpUtils.errorJsonMsg("指定的id错误.");
                }
            }else
                return DpUtils.errorJsonMsg("指定的id错误");
        }else {
            // 自动产生id
            if (insertObjectNode.get("area_code")== null) {
                return DpUtils.errorJsonMsg("缺少area_code");
            }
            areaCode = (String) insertObjectNode.get("area_code");
            if (areaCode.length() != 6) {
                return DpUtils.errorJsonMsg("area_code长度必须为6");
            }
            insertObjectNode.remove("area_code");
            JSONObject criteria = new JSONObject();
            //String id = CommonMethods.generateObjId(ProjectTable.TABLE_NAME,  areaCode, ProjectTable.KEY_PJ_ID, criteria,"", true);

            try {
                id = ObjectUtil.genPjId(areaCode);
                if (id.length() != 4) {
                    throw new IdGenException();
                }
            } catch (IdGenException ex) {
                return DpUtils.errorJsonMsg("ID自动生成失败");
            }
            projectid = areaCode + id;
        }
        //兼容博锐版本修改
        if(insertObjectNode.get("password") == null || insertObjectNode.get("password").toString().length() < 1){
            insertObjectNode.put("password", "123456");
        }
        insertObjectNode.put(ProjectTable.KEY_PJ_ID, projectid);
        if(GeoStaticInfo.codeToNameMap.get(areaCode) == null)
            return DpUtils.errorJsonMsg(areaCode + "是未知地区编码");
        String areaName = GeoStaticInfo.codeToNameMap.get(areaCode);
        JSONObject jsonDataNode = insertObjectNode.containsKey(Const.JSON_FIELD_JSON_DATA_INFOS)? (JSONObject)insertObjectNode.get(Const.JSON_FIELD_JSON_DATA_INFOS) : new JSONObject();
        //jsonDataNode.put("ProjName", areaName + id + "号项目");
        //DfUtils.addCreatTime(jsonDataNode);
        //insertObjectNode.put("project_id", insertObjectNode.get("project_id").toString()); //????
        insertObjectNode.put("valid", true);
        json.put("InsertObject",insertObjectNode);

        log.info(json.toString());
        ObjectIdName name = new ObjectIdName();
        try {
            //String missingInfo = InfosUtil.CheckIntegrityAtCreation(projectid, ObjectType.project, null, jsonDataNode, areaName + id, "Pj" + insertObjectNode.get("project_id").toString(), name);
            String missingInfo = InfosUtil.CheckIntegrityAtCreation(projectid, ObjectType.project, null, jsonDataNode,  "Pj" + insertObjectNode.get("project_id").toString(), name);
            if (missingInfo != null)
                throw new WrongInfosException("信息点名称错误: " + missingInfo);
            CommonUtil.verifyInfosObject(jsonDataNode);
        }catch (Exception ex)
        {
            return DpUtils.errorJsonMsg(ex.getMessage());
        }

        try {
            insertObjectNode.put(ProjectTable.KEY_CREATE_TIME, name.getCreateTime());
            JSONObject re = DpUtils.rmField(ZillionAgentProvider.GetAgent().Query(json));
            if(re.get("Result").equals("failure")) {
                if(re.get("Count")!= null && re.getLongValue("Count") > 0L)
                    throw new Exception("项目已存在!");
                throw new Exception("添加项目失败!");
            }

            JSONArray arr = new JSONArray();
            JSONObject oneObject = new JSONObject();
            oneObject.put(ObjInfosTable.KEY_PJ_ID, projectid);
            oneObject.put(ObjInfosTable.KEY_OBJ_TYPE, "Pj");
            oneObject.put(ObjInfosTable.KEY_OBJ_ID, null);
            oneObject.put(Const.JSON_FIELD_JSON_DATA_INFOS, jsonDataNode);
            arr.add(oneObject);
            ArrayList<String> errors = ObjectUtil.batchUpdate(projectid, arr, false, true, false, new CommonQueryCriteria());
            // 打印错误信息到日志
            if(errors.size() > 0) {
                StringBuilder sb = new StringBuilder();
                for (String error: errors)
                    sb.append(error).append('|');
                log.error(sb.toString());
            }
            ActivityLogUtil.objectLog( "Pj" + projectid,  name.getCreateTime(),"新增一个对象实例", MQType.objectCreate);
            return DpUtils.successJsonMsgWithId("", "Pj" + insertObjectNode.get(ProjectTable.KEY_PJ_ID), name.getNameKey(), name.getNameValue());
        } catch (Exception e) {
            e.printStackTrace();
            return DpUtils.errorJsonMsg(e.getMessage());
        }
    }

    @Path("/delete")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String delete(String jsonStr){
        //return CommonMethods.delete(Const.TABLE_PROJECT_NAME,  "", jsonStr, false);
        try
        {
            JSONObject criteria = JSONObject.parseObject(jsonStr);
            criteria = (JSONObject) criteria.get("criteria");
            if(criteria.get("id") == null || !criteria.get("id").toString().startsWith("Pj"))
                throw new Exception("id错误!");
            // check if can be deleted
            String id = criteria.get("id").toString();
            Set<String> typeSet =  SubsetUtil.findChildrenType(id, id);
            if(typeSet.size() != 0)
                throw new Exception("请先删除项目中的所有对象!");
            // check end.
//            // delete all relations connected to this PjId
//            JSONArray relationArray = new JSONArray();
//            JSONObject from_relation = new JSONObject();
//            from_relation.put("from_id", criteria.get("id").toString());
//            JSONObject to_relation = new JSONObject();
//            to_relation.put("to_id", criteria.get("id").toString());
//            relationArray.add(from_relation);
//            relationArray.add(to_relation);
//            JSONObject obj = new JSONObject();
//            obj.put("criterias", relationArray);
//            log.info(RelationUtil.deleteRelation(criteria.get("id").toString().substring(2), obj.toString()));
            //set valid false;
            JSONObject updateCriteria = new JSONObject();
            JSONObject set = new JSONObject();
            updateCriteria.put(ProjectTable.KEY_PJ_ID, criteria.get("id").toString().substring(2));
            set.put(Const.TABLE_KEY_NAME_VALID, false);
            String time = CommonUtil.getTime();
            set.put(ProjectTable.KEY_DEL_TIME, time);
            JSONObject result = CommonUtil.update(false, HBaseTable.projects, updateCriteria, set);
            if(result.get("Count").equals(0))  // 如果更新失败, 则不往下进行删除信息点
                return DpUtils.errorJsonMsg("删除失败或者没有数据.");
            ActivityLogUtil.objectLog(criteria.get("id").toString(), time, "作废一个对象实例", MQType.objectDelete);
            //CommonUtil.deleteInfoPointToHistory(criteria.get("id").toString().substring(2), Const.OBJ_TYPE_PROJECT, null);
            return DpUtils.successJsonMsg("");
        }catch (Exception ex)
        {
            ex.printStackTrace();
            return DpUtils.errorJsonMsg(ex.getMessage());
        }
    }


    @Path("/query")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String queryPost(@QueryParam(Const.PROJECT_ID) String projectId, String jsonStr) {
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        String customInfo = jsonObject.getString(Const.CUSTOM_INFO);
        return query(projectId, customInfo);
    }

    @Path("/query")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String query(@QueryParam(Const.PROJECT_ID) String projectId, @QueryParam(Const.CUSTOM_INFO) String customInfo){
        ProPasCache.synCache();
        EqStaticInfo eqStaticInfo = new EqStaticInfo(projectId);
        if (Strings.isNullOrEmpty(projectId)) { // 查询所有项目信息
            try {
                JSONObject projects = CommonUtil.query(false, HBaseTable.projects, new JSONObject());
                JSONArray content = (JSONArray) projects.get("Content");
                JSONArray criterias = new JSONArray();
                for(int i = 0 ; i < content.size(); ++i)
                {
                    JSONObject one = new JSONObject();
                    one.put("id", Const.OBJ_TYPE_PROJECT + ((JSONObject)content.get(i)).get(ProjectTable.KEY_PJ_ID));
                    criterias.add(one);
                }
                CommonQueryCriteria cqc = new CommonQueryCriteria();
                if(customInfo != null && customInfo.equals("true"))
                    cqc.setCustomInfo(true);
                return DpUtils.returnJSONArray(CommonUtil.batchQuerySelfInfo(null, criterias, cqc, eqStaticInfo), "");
            } catch (Exception ex) {
                ex.printStackTrace();
                return DpUtils.errorJsonMsg("查询出错:" + ex.getMessage());
            }
        }else{ // 查询单个项目信息
            JSONArray arr = new JSONArray();
            JSONObject obj = new JSONObject();
            obj.put("id", projectId);
            arr.add(obj);
            try {
                CommonQueryCriteria cqc = new CommonQueryCriteria();
                if(customInfo != null && customInfo.equals("true"))
                    cqc.setCustomInfo(true);
                return DpUtils.returnJSONArray(CommonUtil.batchQuerySelfInfo(null, arr, cqc, eqStaticInfo), "");
            }catch (Exception ex)
            {
                ex.printStackTrace();
                return DpUtils.errorJsonMsg("查询出错:" + ex.getMessage());
            }
        }
    }


    @Path("/batch_query")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String batchQuery(String jsonStr){
        try {
            ProPasCache.synCache();
            JSONObject json = JSONObject.parseObject(jsonStr);
            CommonQueryCriteria cqc = CommonUtil.generateCommonQueryCriteria(json);
            JSONArray criteriasNode = (JSONArray) json.get("criterias");
            EqStaticInfo eqStaticInfo = new EqStaticInfo(null);
            JSONArray result = CommonUtil.batchQuerySelfInfo(null, criteriasNode, cqc, eqStaticInfo);
            if(cqc.getNodata())
                return  DpUtils.returnJSONArray(result, "", cqc.getCount());
            return  DpUtils.returnJSONArray(result, "");
        } catch (Exception ex) {
            ex.printStackTrace();
            return DpUtils.errorJsonMsg(ex.getMessage());
        }
    }
}
