/**
 * Copyright &copy; 2013-2017 <a href="http://www.rhcncpa.com/">瑞华会计师事务所</a> All rights reserved.
 */
package com.jeeplus.modules.sys.security;
import com.easemob.server.example.api.impl.EasemobIMUsers;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

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

import com.google.common.collect.Lists;
import com.jeeplus.common.config.Global;
import com.jeeplus.common.oss.OSSClientUtil;
import com.jeeplus.common.utils.*;
import com.jeeplus.modules.sys.dao.UserDao;
import com.jeeplus.modules.sys.entity.Dict;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.sys.entity.Role;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.utils.DictUtils;
import com.jeeplus.modules.tools.utils.TwoDimensionCode;
import io.swagger.client.model.Nickname;
import io.swagger.client.model.RegisterUsers;
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.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.common.json.PrintJSON;
import com.jeeplus.modules.sys.security.SystemAuthorizingRealm.Principal;
import com.jeeplus.modules.sys.service.SystemService;
import com.jeeplus.modules.sys.utils.UserUtils;
import redis.clients.jedis.Jedis;

/**
 * 表单验证（包含验证码）过滤类
 * @author jeeplus
 * @version 2014-5-19
 */
@Service
public class FormAuthenticationMobileFilter 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";

	@Autowired
	private SystemService systemService;
	@Autowired
	private UserDao userDao;

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

	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		Jedis jedis = null;
		try {
			System.out.println("Moblie login");
			HashMap<String, String> requestMap = RequestUtils.findRequestMap((HttpServletRequest) request);
			String randomCode = requestMap.get("randomCode");
			String type = requestMap.get("type");
			String  username = requestMap.get("username");
			String isCodeLogin = requestMap.get("isCodeLogin");
			String registsign = requestMap.get("registsign"); //1代表h5快速登录，即未注册的先注册再登录
			HttpServletRequest httprequest = (HttpServletRequest) request;
			User user = UserUtils.getByLoginNameNoSesion(username);
			String password = requestMap.get("password");
			if (password==null || user==null){
				password = "";
			}
			jedis = JedisUtils.getResource();
			if(StringUtils.isNotBlank(isCodeLogin) && isCodeLogin.equals("yes")){
				//if (randomCode.equals(httprequest.getSession().getServletContext().getAttribute(username)) && type.equals(httprequest.getSession().getServletContext().getAttribute(type))) {
				String a = jedis.get(username);
				String b = jedis.get(type);
				if("1".equals(registsign)) {
					//if (randomCode.equals(httprequest.getSession().getServletContext().getAttribute(username)) && type.equals(httprequest.getSession().getServletContext().getAttribute(type))) {
					if (randomCode.equals(jedis.get(username)) && type.equals(jedis.get(type))){
						if (user != null) {
							password = user.getPasswordRemake();
						}
						//新用户注册
						else {
							User u = new User();
							try {
								u.setName(username);
								String name = u.getName();
								u.setMobile(username);
								// 修正引用赋值问题，不知道为何，Company和Office引用的一个实例地址，修改了一个，另外一个跟着修改。
								List<Dict> dictList = DictUtils.getDictList("defalut_role");
								Dict dict = dictList.get(0);
								Role role = systemService.getRole(dict.getValue());
								// 密码MD5加密
								String upassword = EncrypeUtil.encrypeString("123456", "UTF-8");//默认123456
								u.setPasswordRemake(upassword);
								u.setPassword(SystemService.entryptPassword(upassword));
								u.setLoginName(username);
								// 岗位数据有效性验证，过滤不在授权内的岗位
								/*List<Role> roleList = Lists.newArrayList();
								roleList.add(role);
								u.setRoleList(roleList);*/
								// 生成用户二维码，使用登录名
								long time = System.currentTimeMillis();
								String realPath = Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + time + "/qrcode/";
								FileUtils.createDirectory(realPath);
								String picName = time + ".png"; // encoderImgId此处二维码的图片名
								String filePath = realPath + picName; // 存放路径
								TwoDimensionCode.encoderQRCode(username, filePath, "png");// 执行生成二维码
								u.setQrCode(httprequest.getContextPath() + Global.USERFILES_BASE_URL + time + "/qrcode/" + picName);
								if (u.getQrCode() != null && !u.getQrCode().equals("")) {
									InputStream inputStream = null;
									HttpURLConnection httpURLConnection;
									try {
										URL url = new URL(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + u.getQrCode());
										httpURLConnection = (HttpURLConnection) url.openConnection();
										// 设置网络连接超时时间
										httpURLConnection.setConnectTimeout(3000);
										// 设置应用程序要从网络连接读取数据
										httpURLConnection.setDoInput(true);

										httpURLConnection.setRequestMethod("GET");
										int responseCode = httpURLConnection.getResponseCode();
										if (responseCode == 200) {
											// 从服务器返回一个输入流
											inputStream = httpURLConnection.getInputStream();
										}
										OSSClientUtil ossUtil = new OSSClientUtil();
										String[] arr = u.getQrCode().split("/");
										String qrCodeName = System.currentTimeMillis() + arr[arr.length - 1];
										ossUtil.uploadFile2OSS(inputStream, Global.getRqcode(), qrCodeName);
										u.setQrCode(Global.getAliyunUrl() + "/" + Global.getRqcode() + qrCodeName);
									} catch (MalformedURLException e) {
										e.printStackTrace();
									} catch (IOException e) {
										e.printStackTrace();
									} finally {
										inputStream.close();
									}
								}
								String realPathPhoto = Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + time + "/img/";
								FileUtils.createDirectory(realPathPhoto);
								String picNamePhoto = time + ".png"; // encoderImgId此处二维码的图片名
								String filePathPhoto = realPathPhoto + picNamePhoto; // 存放路径
								//FontImageUtil.createImage(name.substring(0, 1), new Font("宋体", Font.BOLD, 100), new File(filePathPhoto), 200, 200);
								WordToPic.TextToPic(name.substring(name.length() - 2 > 0 ? name.length() - 2 : 0, name.length()), 200, 200, 55, filePathPhoto);
								u.setPhoto(httprequest.getContextPath() + Global.USERFILES_BASE_URL + time + "/img/" + picNamePhoto);
								if (u.getPhoto() != null && !u.getPhoto().equals("")) {
									InputStream inputStream = null;
									HttpURLConnection httpURLConnection;
									try {
										URL url = new URL(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + u.getPhoto());
										httpURLConnection = (HttpURLConnection) url.openConnection();
										// 设置网络连接超时时间
										httpURLConnection.setConnectTimeout(3000);
										// 设置应用程序要从网络连接读取数据
										httpURLConnection.setDoInput(true);

										httpURLConnection.setRequestMethod("GET");
										int responseCode = httpURLConnection.getResponseCode();
										if (responseCode == 200) {
											// 从服务器返回一个输入流
											inputStream = httpURLConnection.getInputStream();

										}
										OSSClientUtil ossUtil = new OSSClientUtil();
										String[] arr = u.getPhoto().split("/");
										String photoName = time + arr[arr.length - 1];
										ossUtil.uploadFile2OSS(inputStream, Global.getPhoto(), photoName);
										u.setPhoto(Global.getAliyunUrl() + "/" + Global.getPhoto() + photoName);
									} catch (MalformedURLException e) {
										e.printStackTrace();
									} catch (IOException e) {
										e.printStackTrace();
									} finally {
										inputStream.close();
									}
								}
								// 保存用户信息
								u.setComId("1");
								u.setDefaultPhoto("0");
								u.setCompany(new Office("1"));
								u.setOffice(new Office("5"));
								systemService.saveUserInfo(u);
								role.setOffice(new Office("5"));
								systemService.assignUserToRole(role, user,0);
								// 清除当前用户缓存
								if (u.getLoginName().equals(UserUtils.getUser().getLoginName())) {
									UserUtils.clearCache();
									//UserUtils.getCacheMap().clear();
								}
								password = upassword;
							} catch (Exception e) {
								e.printStackTrace();
								userDao.delete(u);
							}
						}
					}
				}
				//else if (randomCode.equals(httprequest.getSession().getServletContext().getAttribute(username)) && type.equals(httprequest.getSession().getServletContext().getAttribute(type))) {
				if (randomCode.equals(jedis.get(username)) && type.equals(jedis.get(type))) {
						if (user!=null){
						password =user.getPasswordRemake();
					}
				}
			}
			System.out.println("password="+password);
			boolean rememberMe = false;
			//password = SystemService.entryptPassword(password);
			//boolean rememberMe = (requestMap.get("rememberMe") == "true" ||requestMap.get("rememberMe").equals("1"))?true:false;
			String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
			String captcha = requestMap.get(captchaParam);

			boolean mobile = true;


			return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile);
		} catch (Exception e) {
			//logger.error("getActiveSessions", e);
			return null;
		} finally {
			JedisUtils.returnResource(jedis);
		}
	}

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

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

	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){
			AjaxJson j = new AjaxJson();
            User user = UserUtils.get(p.getId());
			j.setSuccess(true);
			j.setMsg("登录成功!");
            String companyId ="";
            String isManager ="0";
            String companyName =  p.getCompanyName();
            if(UserUtils.getSelectCompany() !=null) {
                companyId = UserUtils.getSelectCompany().getId();
                try {
                    if (UserUtils.isManager()) {
                        isManager = "1";
                    }
                } catch (Exception e) {
                    j.setErrorCode("201");
                    j.setMsg("获取当前用户岗位信息异常");
                    j.setSuccess(true);
                }
            }else{
                companyId =user.getComId();
            }
            if (companyId.equals("1")){
                companyId = "";
                companyName = "";
            }
            j.put("companyId", companyId);
            j.put("isManager", isManager);
			j.put("username", p.getLoginName());
			j.put("name", p.getName());
			j.put("password", user.getPasswordRemake());
			j.put("userId", p.getId());
			j.put("JSESSIONID", p.getSessionid());
			j.put("companyName",companyName );
            j.put("photo",UserUtils.getUser().getPhoto());
			Jedis jedis = null;
			try {
				jedis = JedisUtils.getResource();
				jedis.set(p.getId(),"mobileLogin");
			} catch (Exception e) {
				//logger.error("getActiveSessions", e);
			} finally {
				JedisUtils.returnResource(jedis);
			}
			PrintJSON.write((HttpServletResponse)response, j.getJsonStr());
		}
	}

	/**
	 * 登录失败调用事件
	 */
	@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);
		
		AjaxJson j = new AjaxJson();
		j.setSuccess(false);
		j.setMsg(message);
        j.setErrorCode("-1");
        PrintJSON.write((HttpServletResponse) response, j.getJsonStr());*/
        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;
	}
	
}