package ibase.servlet;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Enumeration;
import java.util.ArrayList;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import ibase.bean.DashboardBean;
import ibase.ejb.CommonDBAccessEJB;
import ibase.system.config.AppConnectParm;
import ibase.utility.BaseException;
import ibase.utility.BaseLogger;
import ibase.utility.CommonConstants;
import ibase.utility.E12GenericUtility;
import ibase.utility.InternalLogger;
import ibase.utility.UserInfoBean;
import ibase.webitm.ejb.ITMDBAccessEJB;
import ibase.webitm.utility.ITMException;

/**
 * @author base71
 * This filter can process all servlet with startswith '/'
 * i.e. servlet with url-pattern "/<servlet-name>"
 *
 */
//Changed by Prasad on 14/02/19 [to authenticate request if network occurs in auto mode, if login happen without server call i.e. using local cache]
//public class SessionTimeoutFilter implements Filter {
public class SessionTimeoutFilter extends AuthenticateServlet implements Filter {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Override
	public void destroy()
	{
		InternalLogger.log("0",null,null,"SessionTimeoutFilter destroyed.");
	}
    @Override
	public void doFilter(ServletRequest req, ServletResponse resp,	FilterChain filterChain) throws IOException, ServletException
	{
		boolean isSessionExpired = false;
		HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        //Added by Pankaj T. on 07-01-2022 for removing vulnerability set httponly and secure flag for cookie - start
        //String sessionid = request.getSession().getId();
        //response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionid + "; HttpOnly;Secure");
        //Added by Pankaj T. on 07-01-2022 for removing vulnerability set httponly and secure flag for cookie - end
        //Added By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - start
//        UserInfoBean userInfo = null;
        HttpSession sessionObj = request.getSession(false);
        //Added by trushant for setting case to differentiate login code [START]
        UserInfoBean userInfo = (UserInfoBean)request.getSession().getAttribute("USER_INFO");
        
        String userId = "";
		Enumeration allParams = request.getParameterNames();
		BaseLogger.log("3",null,null,"SessionTimeoutFilter allParams::"+allParams.toString());
		String allParamsStr = allParams.toString();
		BaseLogger.log("3",null,null,"SessionTimeoutFilter allParamsStr::"+allParamsStr);
		StringBuffer atttsNameAndValue = new StringBuffer();
		while ( allParams.hasMoreElements() )
		{
			String paramName = (String) allParams.nextElement();
			BaseLogger.log("3",null,null,"SessionTimeoutFilter paramName::"+paramName);
			String paramValue = (String)request.getParameter( paramName );
			BaseLogger.log("3",null,null,"SessionTimeoutFilter paramValue::"+paramValue);
			if( "USER".equals( paramName ) )
			{
				userId = paramValue;
			}
			atttsNameAndValue.append( paramName ).append( "=" ).append( paramValue ).append( "&" );
			
			if( userInfo != null )
			{
				userId = userInfo.getLoginCode();
				BaseLogger.log("3",null,null,"SessionTimeoutFilter userId::"+userId);
				if(userId.equalsIgnoreCase("SHILPAM"))
				{
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemoteHost::"+request.getRemoteHost());
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemotePort::"+request.getRemotePort());
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getHeaderNames::"+request.getHeaderNames());
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getPathInfo::"+request.getPathInfo());
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemoteAddr::"+request.getRemoteAddr());
				}
				new E12GenericUtility().writeFile( "FilterComp",  " \n SessionTimeoutFilter : In doFiler() method  userId[,"+userId+",] sessionId[,"+request.getSession().getId()+",] Time[,"+new Date()+",] hostName[,"+userInfo.getHostName()+",] hostIP[,"+userInfo.getHostIP()+",] Attributes[,"+atttsNameAndValue.toString()+",]" );
				if(userInfo.getLoginCode().equalsIgnoreCase("SHILPAM"))
				{
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemoteHost::"+request.getRemoteHost());
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemotePort::"+request.getRemotePort());
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getHeaderNames::"+request.getHeaderNames());
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getPathInfo::"+request.getPathInfo());
					BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemoteAddr::"+request.getRemoteAddr());
				}
			}
		}
		//Added by trushant for setting case to differentiate login code [END]
//        if (requestedCode.equals("SHILPAM")) 
//        {
//        	BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemoteHost::"+request.getRemoteHost());
//        	BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemotePort::"+request.getRemotePort());
//        	BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getHeaderNames::"+request.getHeaderNames());
//        	BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getPathInfo::"+request.getPathInfo());
//        	BaseLogger.log("3",null,null,"SessionTimeoutFilter request.getRemoteAddr::"+request.getRemoteAddr());
//        }
        String errorCode = "SESSIONEXP";
        String authenticatedIP = "";
        String sessionTimeoutIP = "";
        try
        {
            if( sessionObj != null )
            {
                BaseLogger.log("3",null,null,"SessionTimeoutFilter session getting not null");
//                userInfo = (UserInfoBean) sessionObj.getAttribute("USER_INFO");//commited by trushant for testing
                //BaseLogger.log("3",null,null,"SessionTimeoutFilter session userInfo: ["+ userInfo +"]");
                //Added by Jatin on 24-Jun-2022 [To store last access time of session in session object] - START
                String storeSessTime = request.getParameter("STORE_SESS_TIME");
                BaseLogger.log("3",null,null,"SessionTimeoutFilter storeSessTime: ["+ storeSessTime +"]");
                if(!"false".equalsIgnoreCase(storeSessTime))
                {
                    long lastAccessedTimeInmMilliSeconds = sessionObj.getLastAccessedTime();
                    sessionObj.setAttribute("LAST_SRV_CALL", lastAccessedTimeInmMilliSeconds);
                    BaseLogger.log("3",null,null,"SessionTimeoutFilter LAST_SRV_CALL after: ["+ sessionObj.getAttribute("LAST_SRV_CALL") +"]");
                }
                //Added by Jatin on 24-Jun-2022 [To store last access time of session in session object] - END
                if( userInfo == null )
                {
                	BaseLogger.log("3",null,null,"SessionTimeoutFilter session userInfo is null");
                    errorCode = "SESSIONKIL";
                }
            }
            else
            {
                BaseLogger.log("3",null,null,"SessionTimeoutFilter session getting null");
                String hostName = "";
                try 
                {
                    InetAddress inetAddress = InetAddress.getLocalHost();
                    hostName = inetAddress.getHostName();
                    sessionTimeoutIP = inetAddress.getHostAddress();
                    BaseLogger.log("3",null,null,"SessionTimeoutFilter hostName : ["+ hostName +"]");
                    BaseLogger.log("3",null,null,"SessionTimeoutFilter sessionTimeoutIP : ["+ sessionTimeoutIP +"]");
                    if( sessionTimeoutIP != null && sessionTimeoutIP.indexOf(".") != -1 )
                    {
                        sessionTimeoutIP = sessionTimeoutIP.substring( sessionTimeoutIP.lastIndexOf(".") + 1 );
                    }
                } 
                catch (UnknownHostException e) 
                {
                    BaseLogger.log("0",null,null,"Exception while getting inetAddress : ["+ E12GenericUtility.getStackTrace(e) +"]");
                }
                
                Cookie cookie[] = request.getCookies();  
                if( cookie != null )
                {
                    for( int i = 0; i < cookie.length; i++ )
                    {
                        String cookieName = cookie[i].getName();
                        String cookieValue = cookie[i].getValue();
                        BaseLogger.log("3",null,null,"SessionTimeoutFilter cookieName : ["+ cookieName +"]");
                        BaseLogger.log("3",null,null,"SessionTimeoutFilter cookieValue : ["+ cookieValue +"]");
                        if( cookieName.equalsIgnoreCase("authenticatedIP"))
                        {
                            authenticatedIP = cookieValue;
                            BaseLogger.log("3",null,null,"SessionTimeoutFilter cookie authenticatedIP: ["+ authenticatedIP +"]");
                            break;
                        }
                    }
                }

                if( E12GenericUtility.checkNull( sessionTimeoutIP ).length() > 0 && E12GenericUtility.checkNull( authenticatedIP ).length() > 0 && !( sessionTimeoutIP.equals( authenticatedIP ) ) )
                {
                    errorCode = "SESSIONCHG";
                }
                else
                {
                    errorCode = "SESSIONOUT";
                }
            }
        }
        catch(Exception e)
        {
            BaseLogger.log("0",null,null,"SessionTimeoutFilter Exception in session getting invalid :["+E12GenericUtility.getStackTrace(e)+"]");
        }
        //Added By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - end
		String servletPathStr = request.getServletPath();
		servletPathStr = ( servletPathStr == null ) ? "" : servletPathStr;
		//Added by Suraj on 30-Nov-2016 [ To bypass webSocket uri : For Recent Activity related changes ]
		String requestUri = request.getRequestURI();
        //Added By Pankaj T. on 28-07-2020 to handle vulnerability of Host Header Injection in request to validate host when request comes - start
		String requestURL = request.getRequestURL().toString();
		String host = request.getHeader("host");
        //Added By Pankaj T. on 28-07-2020 to handle vulnerability of Host Header Injection in request to validate host when request comes - end
        BaseLogger.log("3",null,null,"SessionTimeoutFilter servletPathStr:["+ servletPathStr +"]");
        BaseLogger.log("3",null,null,"SessionTimeoutFilter requestUri:["+ requestUri +"]");
        BaseLogger.log("3",null,null,"SessionTimeoutFilter requestURL:["+ requestURL +"]");
        BaseLogger.log("3",null,null,"SessionTimeoutFilter host:["+ host +"]");
        
		//Commented by Prajyot on 5MAR2015 [Russian Charatcer issue on ru server]  Starts
//		String hostName="", hostIP="";
//		InetAddress inetAddress;
//		inetAddress = InetAddress.getLocalHost();
//		hostName = inetAddress.getHostName();
//		hostIP = inetAddress.getHostAddress();
//
//		String userId = "";
//		Enumeration allParams = request.getParameterNames();
//		StringBuffer atttsNameAndValue = new StringBuffer();
//		while ( allParams.hasMoreElements() )
//		{
//			String paramName = (String) allParams.nextElement();
//			String paramValue = (String)request.getParameter( paramName );
//			if( "USER".equals( paramName ) )
//			{
//				userId = paramValue;
//			}
//			atttsNameAndValue.append( paramName ).append( "=" ).append( paramValue ).append( "&" );
//
//		}
//		if( userInfo != null )
//		{
//			userId = userInfo.getLoginCode();
//			new E12GenericUtility().writeFile( "FilterComp",  " \n SessionTimeoutFilter : In doFiler() method  userId[,"+userId+",] sessionId[,"+request.getSession().getId()+",] Time[,"+new Date()+",] hostName[,"+userInfo.getHostName()+",] hostIP[,"+userInfo.getHostIP()+",] servlertPathStr[,"+servletPathStr+",] Attributes[,"+atttsNameAndValue.toString()+",]" );
//		}
//		else
//		{
//			new E12GenericUtility().writeFile( "FilterComp",  " \n SessionTimeoutFilter : In doFiler() method  userId[, "+userId+",] sessionId[,"+request.getSession().getId()+",] Time[,"+new Date()+",] hostName[,"+hostName+",] hostIP[,"+hostName+",] servlertPathStr[,"+servletPathStr+",] Attributes[,"+atttsNameAndValue.toString()+",]" );
//		}
		//Commented by Prajyot on 5MAR2015 [Russian Charatcer issue on ru server]  Ends

		//Added by Prajyot on 17APR2014 [To detect Request is from RCP. Get session attribute IS_RCP_REQUEST which set in RequestHandlerServlet ]
        //String isRcpRequestStr = (String) request.getSession().getAttribute("IS_RCP_REQUEST");
        //Added By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - start
        String isRcpRequestStr = "";
        if( sessionObj != null )
        {
            isRcpRequestStr = (String) sessionObj.getAttribute("IS_RCP_REQUEST");
        }
        //Added By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - end
		//BaseLogger.log("9",null,null,"Is RCP REQUEST ["+isRcpRequestStr+"]servletPathStr[" + servletPathStr + "]" );
		//Added By Prajyot P. Rumde on 25-Feb-2014 [To exclude current request from being filtered.]
		//if( excludeFromFilter(servletPathStr) )
		//Changed By Suraj on 30-Nov-2016 [ To exclude websocket call from filter : For Recent Activity related changes ]Start
		if( excludeFromFilter(servletPathStr, requestUri ) || "true".equalsIgnoreCase( isRcpRequestStr ) )
		{
			filterChain.doFilter(request, response);
			return;
		}
		//Changed By Suraj on 30-Nov-2016 [ To exclude websocket call from filter : For Recent Activity related changes]End
		String reqHeader = request.getHeader("User-Agent") ;
		boolean isMobileDevice = false;
		if ( reqHeader.indexOf( "iPhone" ) != -1 )
		{
			isMobileDevice = true;
		}
		else if ( reqHeader.indexOf( "iPad" ) != -1 )
		{
			isMobileDevice = false;
		}
		else if (reqHeader.indexOf("Android") != -1 )
		{
			if( reqHeader.indexOf("Mobile") != -1)
			{
				isMobileDevice = true;
			}
			else
			{
				isMobileDevice = false;
			}
		}
		InternalLogger.log("0",null,null, "@@@@SessionTimeoutFilter Called...  " +
				            "User Agent:[" + reqHeader + "]" +
				            "isMobileDevice:[" + isMobileDevice + "]" +
				            "isIE8[" + ( reqHeader.indexOf("MSIE 8.0;") !=-1 ) + "]" );

		String queryString = request.getQueryString();
		//Changed By Pankaj T. on 21-10-19 check request parameter value if found mismatch then throw "System Inconsistency Detected" error - start
		//BaseLogger.log("9",null,null,"In SessionTimeoutFilter doFilter servletPathStr : ["+servletPathStr+"]");
		//BaseLogger.log("9",null,null,"In SessionTimeoutFilter doFilter queryString : ["+queryString+"]");
		if( E12GenericUtility.checkNull(queryString).length() > 0 )
		{
			queryString = java.net.URLDecoder.decode(queryString, CommonConstants.ENCODING);
			//BaseLogger.log("9",null,null,"In SessionTimeoutFilter doFilter queryString after decode : ["+queryString+"]");
		}
		//Changed By Pankaj T. on 21-10-19 check request parameter value if found mismatch then throw "System Inconsistency Detected" error - end
		//BaseLogger.log("9",null,null,"userInfo[" + (userInfo!=null ? userInfo.toString().length() : userInfo) + "]");
		//BaseLogger.log("9",null,null,"queryString[" + (queryString!=null ? queryString.length() : queryString) + "]");
		//BaseLogger.log("9",null,null,"servletPathStr[" + servletPathStr.length()  + "]" + servletPathStr.lastIndexOf("/") + "]");

		//In authServletPathList, add servlet URL pattern from which authentication will be done.
		//Changes By Prajyot P. Rumde on 30-Jan-2014 Start
		if( CommonConstants.APPLICATION_CONTEXT == null )
		{
			try
			{
				InternalLogger.log("0",null,null,"Setting  IBASE_HOME .............in SessionTimeoutFilter["+ this.servletContext.getRealPath("/") +"]");
				CommonConstants.setAPPLICATION_CONTEXT( this.servletContext.getRealPath("/") );
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		ArrayList<String> authServletPathList = CommonConstants.getAuthServletPathList();//new ArrayList<String>();
		//ArrayList<String> authGwtServletPathList = CommonConstants.getGwtServletPathList();
		//authServletPathList.add("/AuthenticateServlet");
		//authServletPathList.add("/WebITMMobileDataDecodeRequestHandlerServlet");
		//authServletPathList.add("/WebITMMobileDataDecodeRequestHandlerServletMIDP1");
		//Changes By Prajyot P. Rumde on 30-Jan-2014 End

		ArrayList<String> encApplyServletList = new ArrayList<String>();
		encApplyServletList.add("/AuthenticateServlet");
		encApplyServletList.add("/RIAWizardHandlerServlet");
		encApplyServletList.add("/WelcomeMsgServlet");
		encApplyServletList.add("/ME12FavouriteServlet");
		encApplyServletList.add("/WebITMAuthenticateServlet");
		encApplyServletList.add("/StaticDashboardServlet");
		encApplyServletList.add("/ProfileServiceServlet");
		encApplyServletList.add("/WebITMSignAjaxDataServlet");

		//USER_INFO == null means session expired.
		if( userInfo == null )
		{
			// if servletPath is AuthenticateServlet or other than AuthenticateServlet (i.e. files that may be static pages [.html/.jsp/.js] or image files )
			//if( "/AuthenticateServlet".equalsIgnoreCase( servletPathStr ) || servletPathStr.lastIndexOf("/") > 1 || ( queryString != null && queryString.contains("ACTION=LOGIN") ) )
			//Changes By Prajyot P. Rumde on 25-Feb-2014 [Removed condition : servletPathStr.lastIndexOf("/") > 1 ]
			//if( authServletPathList.contains( servletPathStr ) || servletPathStr.lastIndexOf("/") > 1 || ( queryString != null && queryString.contains("ACTION=LOGIN") ) )
			if( authServletPathList.contains( servletPathStr ) || ( queryString != null && queryString.contains("ACTION=LOGIN") ) )
			{
				isSessionExpired = false;
			}
			else
			{
				isSessionExpired = true;
			}
			//Changed by Prasad on 14/02/19 [to authenticate request if network occurs in auto mode, if login happen without server call i.e. using local cache] START
			try 
			{
				InternalLogger.log("0", null, null, "isSessionExpired : ["+ isSessionExpired +"]" );
				if ( isSessionExpired )
				{
					String user = E12GenericUtility.checkNull( request.getParameter( "USER" ) );
					String password = E12GenericUtility.checkNull( request.getParameter( "PASSWORD" ) );
					InternalLogger.log("0", null, null, "USER : ["+ user +"], PASSWORD : ["+ password +"]" );
					if ( user.length() > 0 && password.length() > 0 )
					{
						boolean isValidateUser = Boolean.valueOf( authenticate( request ) ).booleanValue();
						InternalLogger.log("0", null, null, "isValidateUser : ["+ isValidateUser +"]" );
						if ( isValidateUser )
						{
							isSessionExpired = false;
						}
					}
				}
			}
			catch (BaseException e) 
			{
				InternalLogger.log("0", null, null, "SessionTimeoutFilter :: BaseException : ["+ e.getMessage() +"]" );
				e.printStackTrace();
			}
			//Changed by Prasad on 14/02/19 [to authenticate request if network occurs in auto mode, if login happen without server call i.e. using local cache] END
		}
		else
		{
			isSessionExpired = false;
			//Request ID : W15BMIT003 - Set Current Geo Position in Login trace and USER_INFO.
			//Changed by Sagar B. for Geo position related changes for multi tenancy on [11Jan18]
			//if( "true".equalsIgnoreCase( CommonConstants.GEOPOS_ENABLE ) )
			if( !"0".equalsIgnoreCase(userInfo.getGeoPosOption()) )
 			{
				String currentGeoPos = E12GenericUtility.checkNull( request.getParameter("CURRENT_GEO_POS") );
				String dataMode = E12GenericUtility.checkNull( request.getParameter("DATA_MODE") );
				String currentGeoPosName = E12GenericUtility.checkNull( request.getParameter("CURRENT_GEO_POS_NAME") );		//Added by Sagar B. to track address of current geopos and store in table[10-Apr-18]
				String geoPosAccuracy = E12GenericUtility.checkNull( request.getParameter("GEOPOS_ACCURACY") );		//Added by Sagar B. to store accuracy of geo position[23-Jul-18]
				InternalLogger.log("0",null,null,"@SESSION FILTER CURRENT_GEO_POS ["+currentGeoPos+"] CURRENT_GEO_POS_NAME["+currentGeoPosName+"] GEOPOS_ACCURACY["+geoPosAccuracy+"]");
				if( currentGeoPos.length() > 0 && !currentGeoPos.equalsIgnoreCase( userInfo.getCurrentGeoPOS() ) )
				{
					userInfo.setCurrentGeoPOS(currentGeoPos);
					userInfo.setDataMode(dataMode);
					userInfo.setCurrentGeoPOSName(currentGeoPosName);
					userInfo.setGeoPosAccuracy(geoPosAccuracy);		//Added by Sagar B. to store accuracy of geo position[23-Jul-18]
                    //request.getSession().setAttribute("USER_INFO", userInfo);
                    //Added By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - start
                    if( sessionObj != null )
                    {
                        sessionObj.setAttribute("USER_INFO", userInfo);
                    }
                    //Added By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - end

					String deviceUuId = E12GenericUtility.checkNull( request.getParameter( "DEVICEUUID" ) );
					insertGeoPosition(deviceUuId, userInfo);
				}
 			}
		}
		InternalLogger.log("0",null,null,"@@@isSessionExpired ["+isSessionExpired+"]");
		if( isSessionExpired )
		{
            String formData = "";
			try
			{
				//Changes By Prajyot P. Rumde on 30-Jan-2014
				//formData = getErrorString("SESSION_EXPIRED", "E","Session has been expired !","You have not logged on or your session has been expired. \nPlease Re-connect to work on E12");
				//formData = getErrorString( "SESSIONEXP", true );
				response.setHeader("Cache-Control", "no-cache");
				// TODO  : how to check request coming from RCP
				response.setHeader("SessionExpire","true");

				// Added By Arvind on 7-FEB-2014 : Implemented session time out for gwt component as well as for jsp START

				//Changes by Prajyot on 17APR2014 [Added check for isMobileDevice while sending Session timeout message]
                //if( authGwtServletPathList.contains( servletPathStr ) )
                //Commented By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - end
				/*if( authGwtServletPathList.contains( servletPathStr ) || isMobileDevice )
				{
                    formData = getErrorString( "SESSIONEXP", true, userInfo );
					response.setContentType( "text/xml; charset="+CommonConstants.ENCODING );
					response.getWriter().write(formData);
				}
				else
				{
					//Changes by Prajyot P.Rumde on 25-FEB-2014[ In case of non-gwt servlet request set HTML page on response instead of redirecting to any jsp/html page.]
					//response.sendRedirect("/ibase/jsp/login.html");
                    formData = getErrorString( "SESSIONEXP", false, userInfo );
					response.setContentType( "text/html; charset="+CommonConstants.ENCODING );
					response.getWriter().write( getHTMLData(formData) );
                }*/
                //Cpmmented By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - end
                // Added By Arvind on 7-FEB-2014 : Implemented session time out for gwt component as well as for jsp END

                //Added By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - start
                BaseLogger.log("3",null,null,"SessionTimeoutFilter session errorCode:["+ errorCode +"]");
                ITMDBAccessEJB itmDbAccess = new ITMDBAccessEJB();
                formData = itmDbAccess.getErrorString("",errorCode," ", userInfo);
                BaseLogger.log("3",null,null,"SessionTimeoutFilter session timeout message:["+ formData +"]");
                if( "SESSIONCHG".equals( errorCode ) && formData != null && formData.indexOf("<Errors>") != -1 )
                {
                    E12GenericUtility e12GenericUtility = new E12GenericUtility();
                    Document errorDoc = e12GenericUtility.parseString( formData );
					Node errorsNode = errorDoc.getElementsByTagName("error").item(0);
                    String msgDescription = e12GenericUtility.getColumnValueFromNode("description", errorsNode);
                    InternalLogger.log("0",null,null,"SessionTimeoutFilter : Session Timeout msgDescription:["+ msgDescription +"]");
                    LocalDate currentdate = LocalDate.now();
                    int day = currentdate.getDayOfMonth();
                    int month = currentdate.getMonthValue();
                    int hours = LocalDateTime.now().getHour();
                    int minutes = LocalDateTime.now().getMinute();
                    if( msgDescription != null && msgDescription.indexOf("id:") != -1 )
                    {
                        msgDescription = msgDescription.substring( 0, msgDescription.indexOf("id:") + 4 );
                        msgDescription = msgDescription + day + "-" + month + " " + hours + ":" + minutes + ", " + authenticatedIP + ":" +sessionTimeoutIP;
                        InternalLogger.log("0",null,null,"SessionTimeoutFilter : Session Timeout msgDescription after update:["+ msgDescription +"]");
                        formData = e12GenericUtility.updateXMLString("description", msgDescription, formData, userInfo);
                        InternalLogger.log("0",null,null,"SessionTimeoutFilter : Session timeout message after update:["+ formData +"]");
                    }
                }
				response.setContentType( "text/html; charset="+CommonConstants.ENCODING );
                response.getWriter().write(formData);
                //Added By Pankaj T. on 28-09-2020 shown different messages, for the cases of session timeout, session terminated and no session available when accessing application - end
			}
			catch(ITMException item)
			{
				String itmExpMsg = item.getMessage();
				InternalLogger.log("0",null,null,"SessionTimeoutFilter : ITMException Msg[" + itmExpMsg + "]");
				response.setHeader("Cache-Control", "no-cache");

				//Added by Dnyaneshwar Chavan on 24-OCT-13 [CO3ASUN005] [ Resolved the issue of when response in Russian language or etc.  ] START
				//response.setContentType("text/html");
		        response.setContentType( "text/html; charset="+CommonConstants.ENCODING );
		        //Added by Dnyaneshwar Chavan on 24-OCT-13 [CO3ASUN005] [ Resolved the issue of when response in Russian language or etc.  ] END

				response.getWriter().write(itmExpMsg);
			}
			catch(Exception e)
			{
				InternalLogger.log("0",null,null,"SessionTimeoutFilter : Exception in Session Timeout... ["+E12GenericUtility.getStackTrace(e) +"]");
				response.getWriter().write(e.toString());
			}
			InternalLogger.log("0",null,null,"SessionTimeoutFilter : Session Timeout... ");
		}
		else
		{
			//BaseLogger.log("9",null,null,"SessionTimeoutFilter : Normal Request Processing... ");

			//Changes By Prajyot On 9-MAR-2013 [For setting charset in response to support I18N ]Start
			//filterChain.doFilter(req, resp);
			if( encApplyServletList.contains( servletPathStr ) )
			{
				request.setCharacterEncoding(CommonConstants.ENCODING);
				response.setContentType("text/xml; charset="+CommonConstants.ENCODING);
				InternalLogger.log("0",null,null,"SessionTimeoutFilter request.getCharacterEncoding() ["+request.getCharacterEncoding()+"]");
				InternalLogger.log("0",null,null,"SessionTimeoutFilter response.getCharacterEncoding() ["+response.getCharacterEncoding()+"]");
			}
            //Changed By Pankaj T. on 21-10-19 check request parameter value if found mismatch then throw "System Inconsistency Detected" error - start
			try 
			{
				E12GenericUtility e12GenericUtility = new E12GenericUtility();
                String result = e12GenericUtility.checkVulnerability(queryString, servletPathStr, userInfo, requestUri, requestURL, host);
				if( !("".equals(E12GenericUtility.checkNull(result))) )
				{
					//response.setContentType( "text/xml; charset="+CommonConstants.ENCODING );
					//response.getWriter().write(result);
					throw new ITMException( new Exception(result) );
				}
			}
			catch (ITMException itmExp) 
			{
				InternalLogger.log("0",null,null,"SessionTimeoutFilter.doFilter() ITMException :["+itmExp.getMessage()+"]");
				try
				{
					String itmExpMsg = itmExp.getMessage();
					response.setHeader("Cache-Control", "no-cache");
					response.setContentType( "text/html; charset="+CommonConstants.ENCODING );
					response.getWriter().write(itmExpMsg);
					response.getWriter().flush();
					response.getWriter().close();
				}
				catch(Exception ex)
				{
					ex.printStackTrace();
				}
			}
			catch (Exception e) 
			{
				InternalLogger.log("0",null,null,"SessionTimeoutFilter.doFilter() Exception :["+E12GenericUtility.getStackTrace(e)+"]");
				try
				{
					ITMException itmExp = new ITMException(e);
					String itmExpMsg = itmExp.getMessage();
					response.setHeader("Cache-Control", "no-cache");
					response.setContentType( "text/html; charset="+CommonConstants.ENCODING );
					response.getWriter().write(itmExpMsg);
					response.getWriter().flush();
					response.getWriter().close();
				}
				catch(Exception ex)
				{
					ex.printStackTrace();
				}
			}
            //Changed By Pankaj T. on 21-10-19 check request parameter value if found mismatch then throw "System Inconsistency Detected" error - end
            filterChain.doFilter(request, response);
			//Changes By Prajyot On 9-MAR-2013 [For setting charset in response to support I18N ]End
		}
		InternalLogger.log("0",null,null,"SessionTimeoutFilter Ends ");
	}

	//Changes By Prajyot P. Rumde on 30-Jan-2014 Starts
    ServletContext servletContext = null;
    private String[] excludeUrlsPatterns;
	public void init(FilterConfig filterConfig) throws ServletException
 	{
		this.servletContext = filterConfig.getServletContext();
		//Added By Prajyot P. Rumde on 25-Feb-2014 [To prepare excludeUrlsPatterns from initParam] Starts
		String exUrlPattExt = filterConfig.getInitParameter("excludeUrlsPatterns");
		InternalLogger.log("0",null,null, "excludeUrlsPatterns[" + exUrlPattExt + "]" );
		if( exUrlPattExt == null )
		{
			exUrlPattExt = "css,html,js,png,jpg";
		}
		excludeUrlsPatterns = exUrlPattExt.split(",");
		//Added By Prajyot P. Rumde on 25-Feb-2014 [To prepare excludeUrlsPatterns from initParam] Ends
 	}

	/*
	    --Sample query for message definition.
	  	INSERT INTO MESSAGES (MSG_NO,MSG_STR,MSG_DESCR,MSG_TYPE,MSG_OPT,CHG_DATE,CHG_USER,CHG_TERM)
		VALUES ('SESSIONEXP','Session has been expired !','You have not logged on or your session has been expired. \nPlease Re-connect to work on E12','E','Y',sysdate,'sys','sys');
	 */
	//Changes By Prajyot P. Rumde on 26-Sep-2014 [To make use of getErrorString method from ITMDBAccessEJB] Starts
	public String getErrorString( String msgNo, boolean isXML, UserInfoBean userInfo )throws RemoteException,ITMException
 	{

 		String errStringXml = "" ;
		try
		{
			AppConnectParm appConnect = new AppConnectParm();
			InitialContext ctx = new InitialContext( appConnect.getProperty() );
			//ITMDBAccessRemote itmDbAccess = (ITMDBAccessRemote)ctx.lookup("/ibase/ITMDBAccessEJB/remote");
			ITMDBAccessEJB itmDbAccess = new ITMDBAccessEJB();
			errStringXml = itmDbAccess.getErrorString("",msgNo," ", userInfo);
			if( errStringXml != null )
			{
				if( isXML )
				{
					errStringXml = errStringXml.replace("<trace", "<trace type =\"SESSION_EXPIRED\""); // To detect at client side without parsing XML
				}
				else
				{
					E12GenericUtility e12GenUtil = new E12GenericUtility();
					Document errorDoc = e12GenUtil.parseString(errStringXml);
					Node errorsNode = errorDoc.getElementsByTagName("Errors").item(0);

					String msgString = e12GenUtil.getColumnValueFromNode("message", errorsNode);
					String msgDescription = e12GenUtil.getColumnValueFromNode("description", errorsNode);
					errStringXml = msgString + "~SEP~" + msgDescription;
				}
			}
			itmDbAccess = null;
		}
		catch (NamingException e)
		{
			e.printStackTrace();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

 		return errStringXml;
 	}
	//Changes By Prajyot P. Rumde on 26-Sep-2014 [To make use of getErrorString method from ITMDBAccessEJB]Ends

	//Added By Prajyot P. Rumde on 25-Feb-2014 [Helper methods] Starts
	/**
	 * This method checks for url -<br>
	 * if url endswith pattern defined in <b>excludeUrlsPatterns</b> <br>
	 * then <b>return <i>true</i></b>  and does not proceed to Filter.<br>
	 * otherwise <b>return <i>false</i></b>  and proceed to Filter.
	 */
	private boolean excludeFromFilter( String url , String pathUri )
	{
	   int len = excludeUrlsPatterns.length;
	   for (int i = 0; i < len; i++)
	   {
		   String suffix = excludeUrlsPatterns[i];
		   if( url.endsWith(suffix) )
		   {
			   return true;
		   }
		   //Added By Suraj on 30-Nov-2016 [ To exclude websocket call from filter : For Recent Activity related changes ]Start
		   if( pathUri.contains("/ibase/sessionpushnotification/") )
			{
			   return true;
			}
		   //Added By Suraj on 30-Nov-2016 [ To exclude websocket call from filter : For Recent Activity related changes]End
	   }
       return false;
	}

	/**
	 * This method returns HTML string,
	 * in case of non-gwt servlet request came across
	 * then this filter will return HTML page on response
	 * instead of redirecting to any jsp/html page.
	 *
	 */
	private String getHTMLData(String messageStr)
	{
		//Added by shrutika on 16-04-2020 [Start] for display hot ip when session timeout.
		String hostName="", hostIP="";
		try 
		{
			InetAddress inetAddress = InetAddress.getLocalHost();
			hostName = inetAddress.getHostName();
			hostIP = inetAddress.getHostAddress();
		} 
		catch (UnknownHostException e) 
		{
			BaseLogger.log("2",null,null,"Exception while getting  inetAddress **["+ e.getMessage() +"]**");
			e.printStackTrace();
		}
		//Added by shrutika on 16-04-2020 [End] for display hot ip when session timeout.

		String assignLink = "if( window.opener != undefined || window.opener != null ){window.opener.location.assign(\"/ibase/jsp/login.html\" );window.close();}" +
				  			"else{window.parent.location.assign(\"/ibase/jsp/login.html\" );}";
	    String msgArr[] = messageStr.split("~SEP~");
	    StringBuffer strBuffer = new StringBuffer();
	    strBuffer.append( "<html>");
		strBuffer.append( "<body>");
		strBuffer.append( "<h1>Session timeout.</h1>" );
		//Added by shrutika on 16-04-2020 for display hot ip when session timeout.
		if ( hostIP != null && hostIP.trim().length() > 0 )
		{
			strBuffer.append( "<h2>Server IP: "+hostIP+"</h2>" );
		}
		strBuffer.append( "Message : " + msgArr[0] );
		strBuffer.append( "<br/>");
		strBuffer.append( "Description : " + msgArr[1] );
		strBuffer.append( "<br/>" );
		strBuffer.append( "<button onclick=\'" + assignLink + "\'>Click here to Login</button>" );
		strBuffer.append( "</body>");
		strBuffer.append( "</html>");
		return strBuffer.toString();
	}
	//Added By Prajyot P. Rumde on 25-Feb-2014 Ends


	//Added By Prajyot P. Rumde on 01-OCT-15 [GeoPosition Logging in GEOPOS table] Starts
	private void insertGeoPosition(String deviceUuId, UserInfoBean userInfo)
	{
		try
		{
			deviceUuId = ( deviceUuId.length() > 0 ) ? deviceUuId : userInfo.getRemoteHost();
			AppConnectParm appConnect = new AppConnectParm();
			InitialContext ctx = new InitialContext( appConnect.getProperty() );
			// Commented and Added by Pankaj R on 20-JUL-18 to change calling of EJB to JB [START]
			//CommonDBAccessRemote commonDbAccess = (CommonDBAccessRemote)ctx.lookup("/ibase/CommonDBAccessEJB/remote");
			CommonDBAccessEJB commonDbAccess = new CommonDBAccessEJB();
			// Commented and Added by Pankaj R on 20-JUL-18 to change calling of EJB to JB [END]
			//commonDbAccess.insertGeoPosition(userInfo.getLoginCode(), deviceUuId, "", userInfo.getCurrentGeoPOS(), "2", userInfo.getDataMode());
			commonDbAccess.insertGeoPosition(userInfo.getLoginCode(), deviceUuId, "", userInfo.getCurrentGeoPOS(), "2", userInfo.getDataMode(), userInfo.getCurrentGeoPOSName(), userInfo.getGeoPosAccuracy());
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	//Added By Prajyot P. Rumde on 01-OCT-15 Ends
}
