package cn.myapps.runtime.log.aspect.instruction;

import cn.myapps.authtime.department.model.DepartmentVO;
import cn.myapps.authtime.department.service.DepartmentProcess;
import cn.myapps.authtime.domain.model.DomainVO;
import cn.myapps.authtime.domain.service.DomainProcess;
import cn.myapps.authtime.logger.model.LogVO;
import cn.myapps.authtime.user.model.UserVO;
import cn.myapps.authtime.user.service.UserProcess;
import cn.myapps.base.web.WebUser;
import cn.myapps.common.util.StringUtil;
import cn.myapps.runtime.logger.service.LogProcess;
import cn.myapps.util.ProcessFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.json.JSONObject;
import org.aspectj.lang.JoinPoint;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 日记数据库持久化指令
 * @author ekko
 *
 */
public class LogInstruction {

    private final static Map<String, String> METHON_MAP = new HashMap<String, String>();

    private final static Map<String, String> USER_INFO = new HashMap<String, String>();

    private final static Map<String, String> DEPT_INFO = new HashMap<String, String>();

    static {
        //企业域
        METHON_MAP.put("cn.myapps.authtime.domain.controller.DomainAuthtimeController.doCreateDomain", "新建企业域");
        METHON_MAP.put("cn.myapps.authtime.domain.controller.DomainAuthtimeController.doUpdateDomain", "更新企业域");
        METHON_MAP.put("cn.myapps.authtime.domain.controller.DomainAuthtimeController.doDeleteDomain", "删除企业域");

        //部门
        METHON_MAP.put("cn.myapps.authtime.department.controller.DepartmentAuthtimeController.doCreateDepartment", "新建部门");
        METHON_MAP.put("cn.myapps.authtime.department.controller.DepartmentAuthtimeController.doUpdateDepartment", "更新部门");
        METHON_MAP.put("cn.myapps.authtime.department.controller.DepartmentAuthtimeController.doDeleteDepartment", "删除部门");
        //用户
        METHON_MAP.put("cn.myapps.authtime.user.controller.UserAuthtimeController.doCreateUser", "新建用户");
        METHON_MAP.put("cn.myapps.authtime.user.controller.UserAuthtimeController.doUpdateUser", "更新用户");
        METHON_MAP.put("cn.myapps.authtime.user.controller.UserAuthtimeController.doDeleteUser", "删除用户");
        METHON_MAP.put("cn.myapps.authtime.user.controller.UserAuthtimeController.batchAddUser", "批量设置用户角色");
        //软件
        METHON_MAP.put("cn.myapps.authtime.application.controller.ApplicationAuthtimeController.removeApplications", "移除软件");
        METHON_MAP.put("cn.myapps.authtime.application.controller.ApplicationAuthtimeController.addApplications", "添加软件");
        METHON_MAP.put("cn.myapps.authtime.application.controller.ApplicationAuthtimeController.disable", "禁用软件模块");
        METHON_MAP.put("cn.myapps.authtime.application.controller.ApplicationAuthtimeController.enable", "启用软件模块");
        METHON_MAP.put("cn.myapps.authtime.application.controller.ApplicationAuthtimeController.savekmconfig", "保存km角色配置");
        METHON_MAP.put("cn.myapps.authtime.application.controller.ApplicationAuthtimeController.exportRoleMenuAuthority", "导出菜单角色权限关系");
        METHON_MAP.put("cn.myapps.authtime.application.controller.ApplicationAuthtimeController.exportRoleUserAuthority", "导出角色用户权限关系");
        //微信配置
        METHON_MAP.put("cn.myapps.authtime.wechat.controller.WechatAuthtimeController.saveWechatConfig", "保存微信配置");
        METHON_MAP.put("cn.myapps.authtime.wechat.controller.WechatAuthtimeController.synchFromWechat", "同步微信企业号组织架构到企业域");
        METHON_MAP.put("cn.myapps.authtime.wechat.controller.WechatAuthtimeController.synch2Wechat", "同步企业域组织架构到微信企业号");
        //微信配置
        METHON_MAP.put("cn.myapps.authtime.dingding.controller.DingdingAuthtimeController.saveDingdingConfig", "保存钉钉配置");
        METHON_MAP.put("cn.myapps.authtime.dingding.controller.DingdingAuthtimeController.synch2Dingding", "同步企业域组织架构到钉钉");
        METHON_MAP.put("cn.myapps.authtime.dingding.controller.DingdingAuthtimeController.synchFromDingding", "同步钉钉组织架构到企业域");
        //管理员
        METHON_MAP.put("cn.myapps.authtime.admin.controller.AdminAuthtimeController.addAdmins", "添加管理员");
        METHON_MAP.put("cn.myapps.authtime.admin.controller.AdminAuthtimeController.removeAdmins", "移除管理员");
        //工作日历
        METHON_MAP.put("cn.myapps.authtime.workcalendar.controller.CalendarAuthtimeController.addCalendar", "新建工作日历");
        METHON_MAP.put("cn.myapps.authtime.workcalendar.controller.CalendarAuthtimeController.updateCalendar", "更新工作日历");
        METHON_MAP.put("cn.myapps.authtime.workcalendar.controller.CalendarAuthtimeController.deleteCalendar", "删除工作日历");
        //字段扩展
        METHON_MAP.put("cn.myapps.authtime.fieldextends.controller.FieldextendAuthtimeController.updateFieldextend", "更新字段扩展");
        METHON_MAP.put("cn.myapps.authtime.workcalendar.controller.CalendarAuthtimeController.addFieldextends", "新建字段扩展");
        METHON_MAP.put("cn.myapps.authtime.workcalendar.controller.CalendarAuthtimeController.deleteFieldextends", "删除字段扩展");
        //流程监控
        METHON_MAP.put("cn.myapps.authtime.flow.controller.FlowInterventionController.deleteFlowstatert", "删除流程实例");
        METHON_MAP.put("cn.myapps.authtime.flow.controller.FlowInterventionController.doFlow", "干预流程");
        //邮件配置
        METHON_MAP.put("cn.myapps.authtime.email.controller.EmailAuthtimeController.updateEmailConfig", "保存邮件配置");
        //特权用户
        METHON_MAP.put("cn.myapps.authtime.superuser.controller.SuperuserController.saveSuperuser", "更新特权用户");
        METHON_MAP.put("cn.myapps.authtime.superuser.controller.SuperuserController.addSuperuser", "添加特权用户");
        METHON_MAP.put("cn.myapps.authtime.superuser.controller.SuperuserController.deleteSuperuser", "删除特权用户");


        USER_INFO.put("name","姓名");
        USER_INFO.put("loginno","账号");
        USER_INFO.put("level","等级");
        USER_INFO.put("telephone","手机1");
        USER_INFO.put("telephonePublic","手机1公开");
        USER_INFO.put("telephone2","手机2");
        USER_INFO.put("email","电子信箱");
        USER_INFO.put("emailPublic","电子信息公开");
        USER_INFO.put("calendarType","工作日历");
        USER_INFO.put("superiorid","上级");
        USER_INFO.put("_proxyUser","代理人用户");
        USER_INFO.put("remarks","描述");
        USER_INFO.put("startProxyTime","代理开始日期");
        USER_INFO.put("endProxyTime","代理结束日期");
        USER_INFO.put("superAdmin","域(租户)管理员");
        USER_INFO.put("permissionType","通讯录中个人信息");
        USER_INFO.put("allUsers","部门接口人");
        USER_INFO.put("lockFlag","登录异常锁定");
        USER_INFO.put("useIM","使用即时通讯");
        USER_INFO.put("status","是否激活");
        USER_INFO.put("_userRoleDepartmentJson","部门");
        USER_INFO.put("_userKMRoleJson","KM管理");

        DEPT_INFO.put("name","部门名称");
        DEPT_INFO.put("superior","上级部门");
        DEPT_INFO.put("code","代码");
        DEPT_INFO.put("orderByNo","排序号");
    }

    /**
     * 插入指令
     */
    public static final int INSERT_RUNTIME_LOG= 1;

    public static final int INSERT_AUTHTIME_LOG= 2;

    private LogProcess process;

    /**
     * 指令内容（参数）
     */
    private Object content;

    /**
     * 指令类型
     */
    private int actionType;

    private WebUser user;

    private String ip;

    public LogInstruction(Object content, WebUser user,String ip, int actionType){
        this.content = content;
        this.actionType = actionType;
        this.user = user;
        this.ip = ip;
        try {
            this.process = (LogProcess) ProcessFactory.createProcess(LogProcess.class);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void run() throws Exception {
        switch (actionType) {
            case LogInstruction.INSERT_RUNTIME_LOG:
                process.doCreate((LogVO)content);
                break;
            case LogInstruction.INSERT_AUTHTIME_LOG:
                LogVO vo = getLog((JoinPoint) content);
                if(vo!=null)
                    process.doCreate(vo);
                break;
            default:
                break;
        }
    }

    public LogVO getLog(JoinPoint point) throws Exception {
        String description = METHON_MAP.get(point.getSignature().getDeclaringTypeName()+"."+point.getSignature().getName());
        if(!StringUtil.isBlank(description)){
            String domainid = getDomainid(description,point);
            user.setDomainid(domainid);
            LogVO logVo = LogVO.valueOf(user, "企业域",
                    getDescription(description,point), ip);
            return logVo;
        }
        return null;
    }

    public static String getDomainid(String description,JoinPoint point) throws Exception {
        switch (description){
            case "删除企业域":
                DomainProcess  domainProcess = (DomainProcess) ProcessFactory.createProcess(DomainProcess.class);
                DomainVO vo = (DomainVO) domainProcess.doView((String) point.getArgs()[0]);
                return vo.getId();
            case "删除部门":
                DepartmentProcess deptProcess = (DepartmentProcess) ProcessFactory.createProcess(DepartmentProcess.class);
                DepartmentVO department = (DepartmentVO) deptProcess.doView((String)point.getArgs()[0]);
                return department.getDomainid();
            case "删除用户":
                UserProcess userProcess = (UserProcess) ProcessFactory.createProcess(UserProcess.class);
                UserVO user = (UserVO) userProcess.doView((String) point.getArgs()[0]);
                return user.getDomainid();
            default:
                String domainid = (String) point.getArgs()[0];
                return domainid;

        }

    }

    public static String getDescription(String description,JoinPoint point) throws Exception {
        switch (description){
            case "新建用户":
                return compareUser(point);
            case "更新用户":
                return compareUser(point);
            case "保存部门":
                return compareDepartment(point);
            case "更新部门":
                return compareDepartment(point);
            default:
                return description;
        }
    }

    public static String compareUser(JoinPoint point) throws Exception {
        UserProcess userProcess = (UserProcess) ProcessFactory.createProcess(UserProcess.class);
        UserVO user = (UserVO) userProcess.doView((String) point.getArgs()[0]);
        ObjectMapper objectMapper = new ObjectMapper();
        if(user==null){
            user = new UserVO();
        }
        JSONObject oldJson = JSONObject.fromObject(objectMapper.writeValueAsString(user));
        JSONObject newjson = JSONObject.fromObject((String) point.getArgs()[2]);
        Iterator<Map.Entry<String, String>> entrys = USER_INFO.entrySet().iterator();
        String result = "";
        while (entrys.hasNext()){
            Map.Entry<String, String> entry = entrys.next();
            if(("_userRoleDepartmentJson").equals(entry.getKey())){
                result += "["+entry.getValue()+":"+oldJson.get("roleDepartments")+","+newjson.get(entry.getKey())+"],";
            }else {
                result += "["+entry.getValue()+":"+oldJson.get(entry.getKey())+","+newjson.get(entry.getKey())+"],";
            }
        }
        return result;
    }

    public static String compareDepartment(JoinPoint point) throws Exception{
        DepartmentProcess deptProcess = (DepartmentProcess) ProcessFactory.createProcess(DepartmentProcess.class);
        DepartmentVO department = (DepartmentVO) deptProcess.doView((String)point.getArgs()[1]);
        ObjectMapper objectMapper = new ObjectMapper();
        if(department==null){
            department = new DepartmentVO();
        }
        JSONObject oldJson = JSONObject.fromObject(objectMapper.writeValueAsString(department));
        JSONObject newjson = JSONObject.fromObject((String) point.getArgs()[2]);
        Iterator<Map.Entry<String, String>> entrys = DEPT_INFO.entrySet().iterator();
        String result = "";
        while (entrys.hasNext()){
            Map.Entry<String, String> entry = entrys.next();
            if(("superior").equals(entry.getKey())){
                result += "["+entry.getValue()+":"+JSONObject.fromObject(oldJson.get("superior")).get("name")+","+JSONObject.fromObject(newjson.get("superior")).get("name")+"],";
            }else {
                result += "["+entry.getValue()+":"+oldJson.get(entry.getKey())+","+newjson.get(entry.getKey())+"],";
            }
        }
        return result;
    }
}
