package com.guidewire.pl.web.controller;

import com.guidewire.pl.logging.MDCHelper;
import com.guidewire.pl.system.dependency.PLDependencies;
import com.guidewire.pl.system.logging.PLLoggerCategory;
import com.guidewire.pl.system.server.InitTab;
import com.guidewire.pl.system.service.context.ServiceToken;
import com.guidewire.pl.system.servlet.ServletUtilities;
import com.guidewire.pl.web.controller.WebRequestInfo.Util;
import com.guidewire.pl.web.controller.WebServlet.IdleLock;
import com.guidewire.pl.web.render.html.BaseURLBuilderImpl;
import entity.User;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.json.JSONArray;
import org.json.JSONObject;

public final class WebServlet extends HttpServlet {
   private static final String SESSION_LOCK_ATTRIBUTE = "GW_SESSION_LOCK";
   public static final String SERVICE_TOKEN_SESSION_ATTR = "SVC_TKN";
   private static final IdleLock _idleLock = new IdleLock();
   public static final String SERVER_FAILED_TO_START_HTML = "/pages/ServerFailedToStart.html";
   public static final String SERVER_DOWN_HTML = "/pages/ServerDown.html";

   public void init(ServletConfig servletConfig) throws ServletException {
      ServletUtilities.initServletEnvironment(servletConfig.getServletContext());
      PLLoggerCategory.SERVER_RUNLEVEL.debug("Servlet initializing...");

      try {
         super.init();
      } catch (ServletException e) {
         PLLoggerCategory.SERVER_RUNLEVEL.error("Servlet not initialized", e);
         throw e;
      }

      PLLoggerCategory.SERVER_RUNLEVEL.debug("Servlet initialized");
   }

   protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
      this.handleRequest(httpServletRequest, httpServletResponse);
   }

   protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
      this.handleRequest(httpServletRequest, httpServletResponse);
   }

   public void service(ServletRequest request, ServletResponse response) throws IOException, ServletException {
      getIdleLock().lockRead();

      try {
         super.service(request, response);
      } finally {
         getIdleLock().unlockRead();
      }
   }

   private void handleRequest(HttpServletRequest request, HttpServletResponse response) {
      if (!InitTab.getInstance().acceptWebUIRequests()) {
         try {
            Util.setNoCacheHeader(response);
            String serverDownPage = InitTab.getInstance().hasServerStartupFailed() ? "/pages/ServerFailedToStart.html" : "/pages/ServerDown.html";
            String relativePageLocation = PLDependencies.getWebController().getResourcesDir() + serverDownPage;
            boolean isAjaxRequest = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
            if (isAjaxRequest) {
               String baseUrl = BaseURLBuilderImpl.getInstance().getApplicationBaseURL(request);
               response.setHeader("Content-Type", "application/json;charset=utf-8");
               response.getWriter().write(this.createServerDownCommand(baseUrl + "/" + relativePageLocation).toString());
            } else {
               response.sendRedirect(relativePageLocation);
            }
         } catch (IOException var17) {
         }
      } else {
         HttpSession session = request.getSession();
         MDCHelper.configureSession(session);
         synchronized (this.getSessionLock(session)) {
            ServiceToken serviceToken = (ServiceToken)session.getAttribute("SVC_TKN");
            if (serviceToken == null) {
               serviceToken = PLDependencies.getServiceTokenManager().createUnauthenticatedToken();
            }

            int sessionTimeoutSecs = PLDependencies.getServiceTokenManager().touch(serviceToken);
            session.setMaxInactiveInterval(sessionTimeoutSecs);
            PLDependencies.getCommonDependencies().setServiceToken(serviceToken);
            User user = PLDependencies.getCommonDependencies().getCurrentUser();

            try {
               PLDependencies.getWebController().handleRequest(request, response);
            } finally {
               MDCHelper.clearSession();
               ServiceToken newToken = PLDependencies.getCommonDependencies().getServiceToken();
               if (newToken.isAuthenticatedUser()) {
                  request.getSession(false).setAttribute("SVC_TKN", newToken);
               } else {
                  HttpSession sessionIfStillExists = request.getSession(false);
                  if (sessionIfStillExists != null) {
                     sessionIfStillExists.setAttribute("SVC_TKN", null);
                  }

                  PLDependencies.getServiceTokenManager().removeToken(serviceToken);
               }

               PLDependencies.getCommonDependencies().setServiceToken(null);
            }
         }
      }
   }

   private JSONArray createServerDownCommand(String serverDownUrl) {
      return new JSONArray().put(new JSONObject().put("url", serverDownUrl));
   }

   private Object getSessionLock(HttpSession session) {
      Object lock = session.getAttribute("GW_SESSION_LOCK");
      if (lock == null) {
         lock = new Object();
         session.setAttribute("GW_SESSION_LOCK", lock);
      }

      return lock;
   }

   public static IdleLock getIdleLock() {
      return _idleLock;
   }
}
