package com.gzzm.lobster.bootstrap;

import com.gzzm.platform.commons.Tools;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

/**
 * BootstrapServlet —— 容器启动后触发 {@link LobsterBootstrap#onStart(String)} /
 * Servlet that fires the Lobster bootstrap once Tomcat initializes it.
 *
 * <p>zmeg_new 框架没有 Spring 那样的 ApplicationListener；这里借 Servlet 3.0 的
 * {@code load-on-startup} 生命周期作为"容器就绪"信号，在 {@link #init()} 里
 * 通过 {@code Tools.getBean} 取到被 nest DI 注入好的 {@link LobsterBootstrap}
 * 并调一次 {@code onStart(webappRoot)}；同时把 {@code ServletContext.getRealPath("/")}
 * 传给 bootstrap 供 SystemSkillLoader 定位 WEB-INF/skills（生产部署的唯一可靠锚点）。
 *
 * <p>web.xml 中 {@code load-on-startup} 取较大数字，保证晚于 {@code RunStreamServlet}
 * 和框架自身的核心 Servlet 初始化，这样所有 bean 容器此时已经装配完毕。
 */
public class BootstrapServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    public void init() throws ServletException {
        try {
            LobsterBootstrap bootstrap = Tools.getBean(LobsterBootstrap.class);
            if (bootstrap == null) {
                Tools.log("[BootstrapServlet] LobsterBootstrap bean not resolvable — skip");
                return;
            }
            String webappRoot = null;
            try {
                ServletContext ctx = getServletContext();
                if (ctx != null) webappRoot = ctx.getRealPath("/");
            } catch (Throwable ignore) { /* 独立单测或非 servlet 环境 */ }
            bootstrap.onStart(webappRoot);
        } catch (Throwable t) {
            try { Tools.log("[BootstrapServlet] bootstrap invocation failed", t); } catch (Throwable ignore) { /* ignore */ }
        }
    }

    @Override
    public void destroy() {
        try {
            LobsterBootstrap bootstrap = Tools.getBean(LobsterBootstrap.class);
            if (bootstrap != null) {
                bootstrap.onStop();
            }
        } catch (Throwable t) {
            try { Tools.log("[BootstrapServlet] bootstrap shutdown failed", t); } catch (Throwable ignore) { /* ignore */ }
        }
        super.destroy();
    }
}
