package cn.myapps.runtime.macro.controller;

import cn.myapps.common.controller.Resource;
import cn.myapps.runtime.common.controller.AbstractRuntimeController;
import cn.myapps.runtime.macro.runner.DebugFrameInfo;
import cn.myapps.runtime.macro.runner.DebugGui;
import cn.myapps.util.http.CookieUtil;
import com.bcxin.saas.core.InjectResolverFactory;
import com.bcxin.saas.core.components.FeatureOptionChecker;
import com.bcxin.saas.core.components.SessionProvider;
import com.bcxin.saas.core.logs.LoggerEventMessage;
import com.bcxin.saas.core.logs.SysLogProvider;
import com.bcxin.saas.core.utils.ExceptionUtils;
import com.bcxin.saas.logging.LoggerProviderImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Api(tags = "debug调试模块")
@Component
@RequestMapping(path = "/api/runtime", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class MacroController extends AbstractRuntimeController {

    @GetMapping("/macro/log")
    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "宏脚本输出日志文件", notes = "宏脚本输出日志文件")
    public Resource doRunScript() {
                String sessionId = null;
        try {
            sessionId = getUser().getSessionid();
            String clear = request.getParameter("clear");
            Map<String, String> map = new HashMap<>();
            map.put("status", "ok");
            StringBuilder sb = new StringBuilder();
            SessionProvider sessionProvider = InjectResolverFactory.resolve(SessionProvider.class);
            if ("true".equals(clear)) {
                sessionProvider.setAttribute(SysLogProvider.DEBUG_SESSION,new ArrayList<>());
                SysLogProvider.deleteMessages(sessionId);
            } else {
                /*
                Collection<LoggerEventMessage> logMessages = SysLogProvider.getMessages(sessionId);
                logMessages.forEach(lm -> {
                    sb.append(String.format("%s</br>", lm.getMessage()));
                });

                 */
                Collection<LoggerEventMessage> logMessages = sessionProvider.getAttribute(SysLogProvider.DEBUG_SESSION);

                if (!CollectionUtils.isEmpty(logMessages)) {
                    logMessages.forEach(lm -> {
                        sb.append(String.format("%s</br>", lm.getMessage()));
                    });
                } else {
                    sb.append("暂无日志信息...");
                }
            }

            map.put("data", sb.toString());
            map.put("session", sessionId);
            map.put("enableLogging", String.valueOf(FeatureOptionChecker.isEnable(LoggerProviderImpl.JDBC_APPENDER_ENABLED_PRINT_FLAG)));
            Cookie cookie = CookieUtil.getCookie(LoggerProviderImpl.JDBC_APPENDER_ENABLED_PRINT_FLAG, request);
            if (cookie != null) {
                map.put("cookie", cookie.getValue());
            } else {
                map.put("cookie", "NULL");
            }

            return success("ok", map);
        } catch (Exception e) {
            e.printStackTrace();
            return error(500, String.format("Session=%s;enableLogging=%s;detail=%s", sessionId,
                    FeatureOptionChecker.isEnable(LoggerProviderImpl.JDBC_APPENDER_ENABLED_PRINT_FLAG),
                    ExceptionUtils.getStackMessage(e)), null);
        }
    }

    /**
     * 是否开启调式模式
     * @return
     */
    @GetMapping("/macro/isdebug")
    @ApiOperation(value = "是否开启调式模式", notes = "是否开启调式模式")
    public Resource isDebugModule(){
        try {
            boolean result = DebugGui.isDebugModule(getUser().getSessionid());
            return success("ok", result);
        } catch(Exception e) {
            e.printStackTrace();
            return error(500, e.getMessage(), null);
        }
    }

    /**
     * 设置是否开启调式模式
     * @return
     */
    @PutMapping("/macro/debug")
    @ApiOperation(value = "设置是否开启调式模式", notes = "设置是否开启调式模式")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "isDebug",value = "是否开启",required = true,paramType = "query",dataType = "boolean")
    })
    public Resource setDebugModule(boolean isDebug){
        try {
            DebugFrameInfo result = DebugGui.setDebugModule(isDebug, getUser().getSessionid());
            return success("ok", result);
        } catch(Exception e) {
            e.printStackTrace();
            return error(500, e.getMessage(), null);
        }
    }

    /**
     * debug调式模式(刷新操作)
     * @return
     */
    @PutMapping("/macro/refresh")
    @ApiOperation(value = "debug调式模式(刷新操作)", notes = "debug调式模式(刷新操作)")
    public Resource viewDebugFrameInfo(){
        try {
            DebugFrameInfo result = DebugGui.viewDebugFrameInfo("", getUser().getSessionid());
            return success("ok", result);
        } catch(Exception e) {
            e.printStackTrace();
            return error(500, e.getMessage(), null);
        }
    }

    /**
     * debug调式模式(操作)
     *  1.go 进入下一个断点
     *  2.Step Over 单步跳过
     *  3.Step Into 单步进入
     *  4.Step Out 单步退出
     * @return
     */
    @PutMapping("/macro/conduct")
    @ApiOperation(value = "debug调式模式(操作)", notes = "debug调式模式(操作)")
    public Resource actionPerformed(String action){
        try {
            DebugFrameInfo result = DebugGui.actionPerformed(action, getUser().getSessionid());
            return success("ok", result);
        } catch(Exception e) {
            e.printStackTrace();
            return error(500, e.getMessage(), null);
        }
    }

    /**
     * debug调式模式(运行脚本)
     * @return
     */
    @PutMapping("/macro/evalexpr")
    @ApiOperation(value = "debug调式模式(运行脚本)", notes = "debug调式模式(刷新操作)")
    public Resource evalExpr(@RequestBody  String script){
        try {
            String result = DebugGui.evalExpr(script, getUser().getId());
            return success("ok", result);
        } catch(Exception e) {
            e.printStackTrace();
            return error(500, e.getMessage(), null);
        }
    }
}
