package com.example.struts2;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import com.google.gson.Gson;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.*;

/**
 * Action生命周期可视化Action - 展示请求处理完整流程
 * 
 * 学习点：
 * - Action的完整生命周期
 * - 拦截器链的执行过程
 * - 结果渲染流程
 */
public class ActionLifecycleAction extends ActionSupport {
    
    private static final Gson gson = new Gson();
    private static List<String> lifecycleLog = new ArrayList<>();
    
    /**
     * 显示生命周期可视化页面
     */
    public String execute() {
        return SUCCESS;
    }
    
    /**
     * 获取Action生命周期流程（AJAX）
     */
    public String getLifecycle() {
        Map<String, Object> result = new LinkedHashMap<>();
        List<Map<String, Object>> stages = new ArrayList<>();
        
        // 阶段1: 请求接收
        Map<String, Object> stage1 = new LinkedHashMap<>();
        stage1.put("id", 1);
        stage1.put("name", "请求接收");
        stage1.put("icon", "📨");
        stage1.put("description", "客户端发送HTTP请求，被Servlet容器接收");
        stage1.put("components", Arrays.asList("HttpServletRequest", "HttpServletResponse"));
        stage1.put("details", "请求URL、参数、Header等信息被封装到请求对象中");
        stages.add(stage1);
        
        // 阶段2: Filter处理
        Map<String, Object> stage2 = new LinkedHashMap<>();
        stage2.put("id", 2);
        stage2.put("name", "Filter处理");
        stage2.put("icon", "🛡️");
        stage2.put("description", "StrutsPrepareAndExecuteFilter接管请求");
        stage2.put("components", Arrays.asList("StrutsPrepareAndExecuteFilter", "ActionContextCleanUp"));
        stage2.put("details", "过滤器准备ActionContext，设置值栈，创建ActionProxy");
        stages.add(stage2);
        
        // 阶段3: ActionProxy创建
        Map<String, Object> stage3 = new LinkedHashMap<>();
        stage3.put("id", 3);
        stage3.put("name", "ActionProxy创建");
        stage3.put("icon", "🔧");
        stage3.put("description", "根据URL映射创建ActionProxy和ActionInvocation");
        stage3.put("components", Arrays.asList("ActionProxy", "ActionInvocation", "Configuration"));
        stage3.put("details", "从struts.xml查找Action配置，确定拦截器栈和结果映射");
        stages.add(stage3);
        
        // 阶段4: 拦截器前置处理
        Map<String, Object> stage4 = new LinkedHashMap<>();
        stage4.put("id", 4);
        stage4.put("name", "拦截器前置处理");
        stage4.put("icon", "⛓️");
        stage4.put("description", "按顺序执行拦截器的intercept方法");
        stage4.put("components", Arrays.asList("Interceptor", "InterceptorStack"));
        stage4.put("details", "执行日志、权限、校验等前置处理，可中断请求流程");
        stages.add(stage4);
        
        // 阶段5: Action执行
        Map<String, Object> stage5 = new LinkedHashMap<>();
        stage5.put("id", 5);
        stage5.put("name", "Action执行");
        stage5.put("icon", "⚡");
        stage5.put("description", "调用Action的execute或其他指定方法");
        stage5.put("components", Arrays.asList("Action", "ActionSupport", "ModelDriven"));
        stage5.put("details", "执行业务逻辑，操作数据库，返回结果字符串");
        stages.add(stage5);
        
        // 阶段6: 拦截器后置处理
        Map<String, Object> stage6 = new LinkedHashMap<>();
        stage6.put("id", 6);
        stage6.put("name", "拦截器后置处理");
        stage6.put("icon", "↩️");
        stage6.put("description", "拦截器链返回，执行后置处理");
        stage6.put("components", Arrays.asList("Interceptor", "Result"));
        stage6.put("details", "记录执行时间，处理结果，进行资源清理");
        stages.add(stage6);
        
        // 阶段7: 结果渲染
        Map<String, Object> stage7 = new LinkedHashMap<>();
        stage7.put("id", 7);
        stage7.put("name", "结果渲染");
        stage7.put("icon", "🎨");
        stage7.put("description", "根据返回的结果字符串查找并执行Result");
        stage7.put("components", Arrays.asList("Result", "ServletDispatcherResult", "JSP"));
        stage7.put("details", "转发或重定向到视图页面，渲染响应内容");
        stages.add(stage7);
        
        // 阶段8: 响应返回
        Map<String, Object> stage8 = new LinkedHashMap<>();
        stage8.put("id", 8);
        stage8.put("name", "响应返回");
        stage8.put("icon", "📤");
        stage8.put("description", "将渲染后的响应返回给客户端");
        stage8.put("components", Arrays.asList("HttpServletResponse", "OutputStream"));
        stage8.put("details", "清理ActionContext，释放资源，完成请求处理");
        stages.add(stage8);
        
        result.put("stages", stages);
        result.put("totalStages", stages.size());
        
        writeJsonResponse(result);
        return NONE;
    }
    
    /**
     * 获取拦截器链执行流程（AJAX）
     */
    public String getInterceptorChain() {
        Map<String, Object> result = new LinkedHashMap<>();
        List<Map<String, Object>> interceptors = new ArrayList<>();
        
        // 框架级拦截器
        Map<String, Object> i1 = new LinkedHashMap<>();
        i1.put("name", "TimerInterceptor");
        i1.put("type", "framework");
        i1.put("description", "记录Action执行时间");
        i1.put("phase", "前后");
        interceptors.add(i1);
        
        Map<String, Object> i2 = new LinkedHashMap<>();
        i2.put("name", "LoggerInterceptor");
        i2.put("type", "framework");
        i2.put("description", "记录请求日志");
        i2.put("phase", "前置");
        interceptors.add(i2);
        
        Map<String, Object> i3 = new LinkedHashMap<>();
        i3.put("name", "ParametersInterceptor");
        i3.put("type", "framework");
        i3.put("description", "将请求参数设置到Action");
        i3.put("phase", "前置");
        interceptors.add(i3);
        
        Map<String, Object> i4 = new LinkedHashMap<>();
        i4.put("name", "ValidationInterceptor");
        i4.put("type", "framework");
        i4.put("description", "执行数据验证");
        i4.put("phase", "前置");
        interceptors.add(i4);
        
        Map<String, Object> i5 = new LinkedHashMap<>();
        i5.put("name", "WorkflowInterceptor");
        i5.put("type", "framework");
        i5.put("description", "处理验证错误，返回input结果");
        i5.put("phase", "前置");
        interceptors.add(i5);
        
        // 自定义拦截器
        Map<String, Object> i6 = new LinkedHashMap<>();
        i6.put("name", "LoggingInterceptor");
        i6.put("type", "custom");
        i6.put("description", "自定义日志拦截器");
        i6.put("phase", "前后");
        interceptors.add(i6);
        
        Map<String, Object> i7 = new LinkedHashMap<>();
        i7.put("name", "TimingInterceptor");
        i7.put("type", "custom");
        i7.put("description", "自定义计时拦截器");
        i7.put("phase", "前后");
        interceptors.add(i7);
        
        Map<String, Object> i8 = new LinkedHashMap<>();
        i8.put("name", "RateLimitInterceptor");
        i8.put("type", "custom");
        i8.put("description", "限流拦截器");
        i8.put("phase", "前置");
        interceptors.add(i8);
        
        result.put("interceptors", interceptors);
        result.put("chainPattern", "责任链模式");
        result.put("executionOrder", "先入后出（递归调用）");
        
        writeJsonResponse(result);
        return NONE;
    }
    
    /**
     * 模拟请求执行过程（AJAX）
     */
    public String simulateRequest() {
        Map<String, Object> result = new LinkedHashMap<>();
        List<Map<String, Object>> logs = new ArrayList<>();
        
        long startTime = System.currentTimeMillis();
        
        // 模拟每个阶段的执行
        String[] stages = {
            "接收请求: GET /user/list",
            "Filter: StrutsPrepareAndExecuteFilter.doFilter()",
            "创建ActionProxy: UserFormAction.list()",
            "创建ActionInvocation",
            "▶️ 开始拦截器链",
            "  → TimerInterceptor.before()",
            "  → LoggerInterceptor.before()",
            "  → ParametersInterceptor.before()",
            "  → ValidationInterceptor.before()",
            "  → LoggingInterceptor.before()",
            "  → TimingInterceptor.before()",
            "▶️ 执行Action: UserFormAction.list()",
            "  → 查询用户列表",
            "  → 设置userList到值栈",
            "  → 返回结果: SUCCESS",
            "↩️ 拦截器链返回",
            "  → TimingInterceptor.after()",
            "  → LoggingInterceptor.after()",
            "  → ValidationInterceptor.after()",
            "  → ParametersInterceptor.after()",
            "  → LoggerInterceptor.after()",
            "  → TimerInterceptor.after()",
            "▶️ 结果渲染: /user-list.jsp",
            "  → OGNL解析值栈数据",
            "  → 渲染JSP页面",
            "  → 返回响应",
            "✅ 请求完成"
        };
        
        for (int i = 0; i < stages.length; i++) {
            Map<String, Object> log = new LinkedHashMap<>();
            log.put("step", i + 1);
            log.put("message", stages[i]);
            log.put("timestamp", startTime + i * 10);
            log.put("indent", stages[i].startsWith("  ") ? 2 : (stages[i].startsWith("→") ? 1 : 0));
            logs.add(log);
        }
        
        result.put("logs", logs);
        result.put("totalTime", stages.length * 10);
        result.put("interceptorCount", 6);
        result.put("actionTime", 10);
        result.put("renderTime", 20);
        
        writeJsonResponse(result);
        return NONE;
    }
    
    /**
     * 获取值栈信息（AJAX）
     */
    public String getValueStack() {
        Map<String, Object> result = new LinkedHashMap<>();
        
        List<Map<String, Object>> stack = new ArrayList<>();
        
        Map<String, Object> root = new LinkedHashMap<>();
        root.put("name", "CompoundRoot");
        root.put("type", "root");
        root.put("description", "值栈的根对象列表");
        root.put("objects", Arrays.asList(
            mapOf("name", "当前Action", "type", "UserFormAction", "properties", "userList, user, id"),
            mapOf("name", "模型对象", "type", "User", "properties", "id, name, email, age")
        ));
        stack.add(root);
        
        Map<String, Object> context = new LinkedHashMap<>();
        context.put("name", "ActionContext");
        context.put("type", "context");
        context.put("description", "Action上下文");
        context.put("objects", Arrays.asList(
            mapOf("name", "request", "type", "HttpServletRequest", "properties", "参数、Header、Attribute"),
            mapOf("name", "session", "type", "HttpSession", "properties", "会话数据"),
            mapOf("name", "application", "type", "ServletContext", "properties", "应用级数据"),
            mapOf("name", "parameters", "type", "Map", "properties", "请求参数"),
            mapOf("name", "attr", "type", "Map", "properties", "属性查找")
        ));
        stack.add(context);
        
        result.put("stack", stack);
        result.put("ognl", "OGNL表达式用于访问值栈中的数据");
        result.put("examples", Arrays.asList(
            "user.name - 访问Action的user对象的name属性",
            "#session.user - 访问session中的user",
            "#request.ip - 访问request中的ip属性",
            "userList.size() - 调用userList的size方法"
        ));
        
        writeJsonResponse(result);
        return NONE;
    }
    
    /**
     * 辅助方法：创建Map
     */
    private Map<String, String> mapOf(String... pairs) {
        Map<String, String> map = new LinkedHashMap<>();
        for (int i = 0; i < pairs.length; i += 2) {
            map.put(pairs[i], pairs[i + 1]);
        }
        return map;
    }
    
    /**
     * 辅助方法：写入JSON响应
     */
    private void writeJsonResponse(Map<String, Object> data) {
        try {
            ServletActionContext.getResponse().setContentType("application/json;charset=UTF-8");
            PrintWriter out = ServletActionContext.getResponse().getWriter();
            out.print(gson.toJson(data));
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
