package net.northking.cctp.se.debug.bean;



import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.northking.cctp.element.core.exception.ExecuteException;
import net.northking.cctp.se.util.JsonUtils;


import javax.websocket.Session;
import java.util.HashMap;
import java.util.Map;
@Data
@Slf4j
public class DebuggerResponse {

    private String sessionId;
    private String cmd;
    private Map<String,Object> data;

    public static DebuggerResponse newResponse(){
        return new DebuggerResponse().cmd(DebugerConst.ReplyConst.KEY_CMD_REPLY);
    }
    public DebuggerResponse sessionId(String sessionId){
        this.sessionId = sessionId;
        return  this;
    }
    public DebuggerResponse cmd(String cmd){
        this.cmd = cmd;
        return  this;
    }

    public DebuggerResponse withData(String key, Object val){
        if (null == data){
            data = new HashMap<>();
        }
        data.put(key,val);
        return this;
    }
    public DebuggerResponse withResult(String key, Object val){
        if (null == data){
            data = new HashMap<>();
        }
        Map<String,Object> ret = (Map<String, Object>) data.get(DebugerConst.ReplyConst.KEY_RESULT);
        if (null == ret) {
            ret = new HashMap<>();
        }
        ret.put(key,val);
        data.put(DebugerConst.ReplyConst.KEY_RESULT, ret);
        return this;
    }
    public DebuggerResponse withResult(Map<String,Object> resultData){
        if (null == resultData){
            return this;
        }
        if (null == data){
            data = new HashMap<>();
        }
        Map<String,Object>  result = (Map<String, Object>) data.get(DebugerConst.ReplyConst.KEY_RESULT);
        if (null == result){
            result  = new HashMap<>();
        }
        result.putAll(resultData);
        data.put(DebugerConst.ReplyConst.KEY_RESULT, result);
        return this;
    }
    public DebuggerResponse requestId(String requestId){
        return withData(DebugerConst.ReplyConst.KEY_REQUEST_ID,requestId);
    }
    public DebuggerResponse result(Map<String,Object> result){
        return withData(DebugerConst.ReplyConst.KEY_RESULT,result);
    }
    public DebuggerResponse msg(String msg){
        return withData(DebugerConst.ReplyConst.KEY_MSG,msg);
    }
    public DebuggerResponse finish(boolean done){
        return withData(DebugerConst.ReplyConst.KEY_FINISH,done);
    }
    public DebuggerResponse success(boolean success){
        return withData(DebugerConst.ReplyConst.KEY_SUCCESS,success);
    }

    public DebuggerResponse log(String logContent, String logLevel, String title) {
        return withData("log", logContent)
                .withData("level", logLevel)
                .withData("title", title)
                .withData("logType", "TEXT")
                .withData("time", System.currentTimeMillis())
                .withData("stepType", "basic");
    }
    public DebuggerResponse withData(Map<String,Object> data){
        if (null == data){
            return this;
        }
        if (null == this.data){
            this.data = new HashMap<>();
        }
        this.data.putAll(data);
        return this;
    }

    public DebuggerResponse send(Session session) {
        if (session.isOpen()) {
            send(session, sessionId, JsonUtils.toJson(this));
        } else {
            log.info("session通道已关闭，发送信息失败");
        }
        return this;
    }


    public static synchronized void send(Session session, String sessionId, String msg) {
        if (session != null) {
            try {
                if(!Thread.currentThread().isInterrupted()){
                    session.getBasicRemote().sendText(msg);
                }
            } catch(IllegalStateException e) {
                if (e.getMessage().contains("TEXT_FULL_WRITING")) {
                    throw new ExecuteException("发送信息失败：信息通道并发异常", e);
                }
                throw e;
            } catch (Exception e) {
                throw new ExecuteException("发送消息失败", e);
            }
        }
    }

    public String getSessionId() {
        return sessionId;
    }

    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }



}
