package com.iamberry.wechat.core.entity;

import java.security.SecureRandom;
import java.util.Date;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.iamberry.app.tool.des.MD5;
import com.iamberry.app.tool.log.RatFWLogger;
import com.iamberry.wechat.core.entity.admin.AdminLoginDTO;

@Component
public class AdminUtils {
	
	public static void addAdminUserToSession(Object object, HttpServletRequest request) {
		// 一旦登陆成功，就改变sessionID的值，防止发生session fixation
//		request.getSession().invalidate();
//		DefaultHTTPUtilities defaultHTTPUtilities = new DefaultHTTPUtilities();
//		HttpSession session = null;
//		try {
//			session = defaultHTTPUtilities.changeSessionIdentifier(request);
//		} catch (AuthenticationException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		HttpSession session = request.getSession(true);
		request.getSession().setAttribute("login_admin_userinfo", object);
	}
	
	public static Object getLoginAdminUser(HttpSession session) {
		return session.getAttribute("login_admin_userinfo");
	}
	
	@Autowired
	private RatFWLogger logger;
	public void setLogger(RatFWLogger logger) {
		this.logger = logger;
	}
	
	
	/**
	 * 设置用户信息到response，而后保存到cookie
	 * @param response
	 * @param name
	 * @param pwd
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	public void setCookieToResponse(HttpServletResponse response, String name, String pwd) throws Exception {
		// 账户信息
		StringBuffer buffer = new StringBuffer("");
		buffer.append(name).append("-").append(pwd).append("adminuserlogin");
		MD5 md5 = new MD5("loginadmin");
		createCookie(response, "d42b2423_ratfw7d5f4he0d2c5_acoolrat0ed655cbf3d2cd", md5.encrypt(buffer.toString()));
		// 账户信息有效时
		Date date = new Date();
		date.setDate(date.getDate()+7);
		createCookie(response, "t3dt5f89df3jlk35kdf-093_da_dk3kj5d0", md5.encrypt(date.getTime()+"datetimelong"));
		// 安全的随机数
		String str = byte2hex(createRandomByte());
		createCookie(response, "8dk3d435kj4d9d834kjgfh54k3_435j", str);
		// 加密安全的随机数
		createCookie(response, "3k5k49dhjkj45j3j65-5k_52", md5.encrypt(str));
	}
	
	/**
	 * 创建cookie，并保存到response中，写入客户端
	 * @param response
	 * @param name
	 * @param value
	 */
	public static void createCookie(HttpServletResponse response, String name, String value) {
		Cookie cookie = new Cookie(name,value);
		cookie.setMaxAge(604800);
//		cookie.setDomain(".acoolrat.com"); // 一旦正式的环境，使用此
		cookie.setPath("/"); // 一旦正式的环境，使用此
		cookie.setHttpOnly(true);
		response.addCookie(cookie);
	}



	/**
	 * 解析当前浏览器是否登陆过我们的后台，名称为:d42b2423_ratfw7d5f4he0d2c5_acoolrat0ed655cbf3d2cd
	 * @param request
	 * @throws Exception
	 */
	public AdminLoginDTO parseCookieAdminUser(HttpServletRequest request, MD5 md5test) throws Exception {
		try {
			// 时间校验
			MD5 md5 = new MD5("loginadmin");
			Cookie[] cookies = request.getCookies();//这样便可以获取一个cookie数组
			String timeStr = null; // 有效期加密值
			String md5Str = null; // 用户信息加密值
			String random = null; // 安全的随机数
			String randomMd5 = null; // 安全随机数的加密值
			for(Cookie cookie : cookies){
				if (cookie.getName().equals("t3dt5f89df3jlk35kdf-093_da_dk3kj5d0")) {
					timeStr = md5.decrypt(cookie.getValue());
					timeStr = timeStr.replaceAll("datetimelong", "");
				} else if (cookie.getName().equals("d42b2423_ratfw7d5f4he0d2c5_acoolrat0ed655cbf3d2cd")) {
					String value = cookie.getValue(); // 此数据为加密后的信息
					md5Str = md5.decrypt(value); // 解密
				} else if (cookie.getName().equals("8dk3d435kj4d9d834kjgfh54k3_435j")) {
					random = cookie.getValue();
				} else if (cookie.getName().equals("3k5k49dhjkj45j3j65-5k_52")) {
					randomMd5 = md5.decrypt(cookie.getValue());
				}
			}
			if (timeStr == null || "".equals(timeStr)) {
				return null;
			}
			if (new Date(Long.parseLong(timeStr)).getTime() < new Date().getTime()) {
				return null;
			}
			if (!randomMd5.equals(random)) {
				return null;
			}
			if (md5Str.indexOf("adminuserlogin") != -1) {
				String str = md5Str.replaceAll("adminuserlogin", "");
				String[] infos = str.split("-");
				if (infos.length == 2) {
					AdminLoginDTO dto = new AdminLoginDTO();
					dto.setAdminLoginName(infos[0]);
					dto.setAdminLoginPwd(md5test.decrypt(infos[1]));
					return dto;
				}
			}
			// 解析信息
		} catch (Exception e) {
			// 不处理,只记录，交由程序员处理
		}
		return null;
	}

	/**
	 * 创建后台登陆时需要的token
	 * @param session
	 */
	public void createRandom(HttpSession session) {
		try {
			session.setAttribute("loginToken", byte2hex(createRandomByte()));
		} catch (Exception e) {
			session.setAttribute("loginToken", UUID.randomUUID().toString());
		}
	}
	
	/**
	 * 创建一个安全的随机数组byte[]
	 * @return
	 */
	public byte[] createRandomByte() {
		try {
			SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
			byte[] bytes = new byte[1024 / 8];
			random.nextBytes(bytes);
			int count = 10;
			byte[] seed = random.generateSeed(count);
			random = SecureRandom.getInstance("SHA1PRNG");
			random.setSeed(seed);
			SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG");
			random2.setSeed(seed);
			return seed;
		} catch (Exception e) {
			return UUID.randomUUID().toString().getBytes();
		}
	}
	
	/**
	 * Function description: 向session中添加一个token
	 * Return Value:boolean true:添加成功，false:添加是吧
	 * Param value: tokenName，session
	 * Exception Info: 无
	 * Create User: 何秀刚
	 */
	public String saveTokenToSession(String tokenName, HttpSession session) {
		try {
			String token = byte2hex(createRandomByte());
			session.setAttribute(tokenName, token);
			return token;
		} catch (Exception e) {
			// TODO: handle exception
			return null;
		}
	}

	/**
	 * byte[] 转 字符串
	 * @param b
	 * @return
	 */
	public String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
		}
		return hs.toUpperCase();
	}
	
	/**
	 * 校验session中的token
	 * @param token
	 * @return
	 */
	public boolean checkLoginToken(String token, HttpSession session) {
		if (!(token != null && !"".equals(token))) {
			return false;
		}
		String sessionToken = (String) session.getAttribute("loginToken");
		if (!(sessionToken != null && !"".equals(sessionToken))) {
			return false;
		}
		if (token.equals(sessionToken)) {
			return true;
		} else {
			return false;
		}
	}
	
	public boolean checkToken(String token, String tokenName, HttpSession session) {
		if (!(token != null && !"".equals(token))) {
			return false;
		}
		String sessionToken = (String) session.getAttribute(tokenName);
		if (!(sessionToken != null && !"".equals(sessionToken))) {
			return false;
		}
		if (token.equals(sessionToken)) {
			session.removeAttribute(tokenName);
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 验证码校验
	 * @param session
	 * @param verifyCode
	 * @return
	 */
	public boolean checkVerifyCode(HttpSession session, String verifyCode) {
		if (!(verifyCode != null && !"".equals(verifyCode))) {
			return false;
		}
		String sessionCode = (String) session.getAttribute("verifyCode");
		if (!(sessionCode != null && !"".equals(sessionCode))) {
			return false;
		}
		if (verifyCode.equalsIgnoreCase(sessionCode)) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * 对object对象加盐后加密
	 * @param obj 需要加密的元数据
	 * @param salting 加盐值
	 * @return
	 * @throws Exception 
	 */
	public String encryptObject(Object obj, final String salting) throws Exception {
		String str = "";
		if (obj instanceof String) {
			str = salting + obj.toString();
		} else if (obj instanceof Integer) {
			str = salting + obj;
		} else {
			str = salting + obj.hashCode();
		}
		MD5 md5 = new MD5(salting);
		return md5.encrypt(str);
	}
	
	/**
	 * 对加盐后加密的数据解析
	 * @param str 加密后的数据
	 * @param salting 加盐值
	 * @return
	 */
	public String decryptObject(String str, final String salting) {
		try {
			MD5 md5 = new MD5(salting);
			str = md5.decrypt(str);
			return str.replaceAll(salting, "");
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * 字段长度验证
	 * @param args
	 * @throws Exception
	 */
	public boolean parseFieldLength(String str,int minLength, int maxLength) {
		if(str != null && str != "") {
			int strLength = str.length();
			if(strLength >= minLength && strLength <= maxLength) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
}
