/**
 * Copyright &copy; 2013-2017 <a href="http://www.rhcncpa.com/">瑞华会计师事务所</a> All rights reserved.
 */
package com.jeeplus.modules.sys.security;

import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.common.json.PrintJSON;
import com.jeeplus.common.utils.JedisUtils;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.security.SystemAuthorizingRealm.Principal;
import com.jeeplus.modules.sys.service.SystemService;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 表单验证（包含验证码）过滤类
 * @author jeeplus
 * @version 2014-5-19
 */
@Service
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {

	public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
	public static final String DEFAULT_MOBILE_PARAM = "mobileLogin";
	public static final String DEFAULT_MESSAGE_PARAM = "message";
	public static final String DEFAULT_COMPANY_PARAM = "companyName";

	private String captchaParam = DEFAULT_CAPTCHA_PARAM;
	private String mobileLoginParam = DEFAULT_MOBILE_PARAM;
	private String messageParam = DEFAULT_MESSAGE_PARAM;
	private String companyParam = DEFAULT_COMPANY_PARAM;

	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		Jedis jedis = null;
		try {
			System.out.println("Web login");
			String username = getUsername(request);
			String password = getPassword(request);
			HttpServletRequest httpRequest = (HttpServletRequest)request;
			String isCodeLogin = httpRequest.getParameter("isCodeLogin");
			String randomCode = httpRequest.getParameter("randomCode");
			//String sessionType = httpRequest.getParameter("type");
			User user = UserUtils.getByLoginNameNoSesion(username);

			if (password==null || user==null){
				password = "";
			}else{
				password = SystemService.encrypeString(password);
			}
			jedis = JedisUtils.getResource();
			if(StringUtils.isNotBlank(isCodeLogin)&& isCodeLogin.equals("yes")){
				//String sessionRandomCode = (String)httpRequest.getSession().getServletContext().getAttribute(username);
				//String sessionType = (String) httpRequest.getSession().getServletContext().getAttribute("type");
				String sessionRandomCode = (String)jedis.get(username);
				String sessionType = (String)jedis.get("type");
				if (randomCode.equals(sessionRandomCode)&&"2".equals(sessionType)) {
					if (user!=null){
						password =user.getPasswordRemake();
					}else{
						password = "";
					}
				}else {
					password = "";
				}
			}
			System.out.println("password="+password);
			boolean rememberMe = isRememberMe(request);
			String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
			String captcha = getCaptcha(request);
			boolean mobile = isMobileLogin(request);
			return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile);
		} catch (Exception e) {
			//logger.error("getActiveSessions", e);
			return null;
		} finally {
			JedisUtils.returnResource(jedis);
		}
	}

	public String getCaptchaParam() {
		return captchaParam;
	}

	protected String getCaptcha(ServletRequest request) {
		return WebUtils.getCleanParam(request, getCaptchaParam());
	}

	public String getComapnyParam() {
		return companyParam;
	}
	
	protected String getComapnyName(ServletRequest request) {
		return WebUtils.getCleanParam(request, getComapnyParam());
	}
	
	public String getMobileLoginParam() {
		return mobileLoginParam;
	}
	
	protected boolean isMobileLogin(ServletRequest request) {
        return WebUtils.isTrue(request, getMobileLoginParam());
    }
	
	public String getMessageParam() {
		return messageParam;
	}
	
	/**
	 * 登录成功之后跳转URL
	 */
	public String getSuccessUrl() {
		return super.getSuccessUrl();
	}
	
	@Override
	protected void issueSuccessRedirect(ServletRequest request,
			ServletResponse response) throws Exception {
		Principal p = UserUtils.getPrincipal();
		if (p != null && !p.isMobileLogin()){
			 WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
		}else{
			//super.issueSuccessRedirect(request, response);//手机登录
			AjaxJson j = new AjaxJson();
			j.setSuccess(true);
			j.setMsg("登录成功!");
			j.put("username", p.getLoginName());
			j.put("name", p.getName());
			j.put("mobileLogin", p.isMobileLogin());
			j.put("JSESSIONID", p.getSessionid());
			PrintJSON.write((HttpServletResponse)response, j.getJsonStr());
		}
	}

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
	{
		if (isLoginRequest(request, response))
		{
			if (isLoginSubmission(request, response))
			{
				return false;
				/*//本次用户登陆账号
				String account = this.getUsername(request);
				System.out.println("isAccessAllowed-account:"+account);
				Subject subject = this.getSubject(request, response);
				//之前登陆的用户
				Principal principal = (Principal)subject.getPrincipal();
				//如果两次登陆的用户不一样，则先退出之前登陆的用户
				if (account != null && principal != null)
				{
					subject.logout();
				}*/
			}
		}

		return super.isAccessAllowed(request, response, mappedValue);
	}

	/**
	 * 登录失败调用事件
	 */
	@Override
	protected boolean onLoginFailure(AuthenticationToken token,
			AuthenticationException e, ServletRequest request, ServletResponse response) {
		String className = e.getClass().getName(), message = "";
		if (IncorrectCredentialsException.class.getName().equals(className)
				|| UnknownAccountException.class.getName().equals(className)){
			message = "用户或密码错误, 请重试.";
		}
		else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
			message = StringUtils.replace(e.getMessage(), "msg:", "");
		}
		else{
			message = "系统出现点问题，请稍后再试！";
			e.printStackTrace(); // 输出到控制台
		}
        request.setAttribute(getFailureKeyAttribute(), className);
        request.setAttribute(getMessageParam(), message);
        return true;
	}
	
}