package jetbrains.buildServer.flex.controller;


import flex.messaging.MessageBrokerServlet;
import jetbrains.buildServer.controllers.BaseController;
import jetbrains.buildServer.serverSide.SBuildServer;
import jetbrains.buildServer.web.openapi.PluginDescriptor;
import jetbrains.buildServer.web.openapi.WebControllerManager;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Hashtable;

/**
 * Our sample controller
 */
public class BlazeDsController extends BaseController {
    private final WebControllerManager myManager;
    private final PluginDescriptor myDescriptor;
    private MessageBrokerServlet myFlexMsgBroker;

    public BlazeDsController(SBuildServer sBuildServer, WebControllerManager manager,
                             final PluginDescriptor descriptor) {

        super(sBuildServer);
        myManager = manager;
        myDescriptor = descriptor;
    }

    /**
     * Main method which works after user presses 'Hello' button.
     *
     * @param httpServletRequest  http request
     * @param httpServletResponse http response
     * @return object containing model object and view (page aggress)
     * @throws Exception
     */
    protected ModelAndView doHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        /*SUser user = SessionUser.getUser(httpServletRequest);
        HashMap params = new HashMap();
        params.put("userName", user.getDescriptiveName());
        params.put("messages", myLoggingListener.getMessages());
        return new ModelAndView("/plugins/samplePlugin/hello.jsp", params);*/

        myFlexMsgBroker.service(httpServletRequest, httpServletResponse);
        return null;
    }

    public void register() {
        myManager.registerController("/messagebroker/*", this);
        initMessageBroker();
    }

    private WebApplicationContext findWebApplicationContext() {
        // workaround for http://jetbrains.net/tracker/issue2/TW-7656
        for (ApplicationContext ctx = getApplicationContext(); ctx != null; ctx = ctx.getParent()) {
            if (ctx instanceof WebApplicationContext) {
                return (WebApplicationContext)ctx;
            }
        }
        throw new RuntimeException("WebApplication context was not found.");
    }


    private void initMessageBroker() {
        myFlexMsgBroker = new MessageBrokerServlet();

        final ServletContext finalCtx = findWebApplicationContext().getServletContext();

        String path = myDescriptor.getPluginResourcesPath("flex/services-config.xml");
        final InputStream resourceAsStream = getClass().getResourceAsStream(path);
        assert null != resourceAsStream;

        ServletConfig servletConfig = new ContextAwareServletConfig(finalCtx, getApplicationContext(), myDescriptor);
        try {
            myFlexMsgBroker.init(servletConfig);
        } catch (ServletException e) {
            System.out.println(e);
        }
    }

    public static class ContextAwareServletConfig implements ServletConfig {
        final Hashtable<String, String> initParams;
        private final ServletContext myServletContext;
        private ApplicationContext myAppContext;

        public ContextAwareServletConfig(ServletContext servletContext,
                                         ApplicationContext applicationContext,
                                         final PluginDescriptor descriptor) {
            myServletContext = servletContext;
            myAppContext = applicationContext;
            initParams = new Hashtable<String, String>() {{
                put("services.configuration.file", descriptor.getPluginResourcesPath("flex/services-config.xml"));
            }};
        }

        public String getServletName() {
            return "messageBrokerServlet";
        }

        public ServletContext getServletContext() {
            return myServletContext;
        }

        public String getInitParameter(String s) {
            return initParams.get(s);
        }

        public Enumeration getInitParameterNames() {
            return initParams.keys();
        }

        public ApplicationContext getAppContext() {
            return myAppContext;
        }
    }
}
