package jp.yoyoyoyo.webformmanager.action;

import java.security.MessageDigest;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;

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

import jp.yoyoyoyo.webformmanager.dao.ExecuteLoginDAO;
import jp.yoyoyoyo.webformmanager.dao.MstUserDAO;
import jp.yoyoyoyo.webformmanager.form.LoginForm;
import jp.yoyoyoyo.webformmanager.model.LoginInfo;
import jp.yoyoyoyo.webformmanager.model.MstUser;
import jp.yoyoyoyo.webformmanager.util.CommonUtil;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;

public class LoginAction extends Action {
	public ActionForward execute(ActionMapping mapping,
			ActionForm form,
			HttpServletRequest request,
			HttpServletResponse response){
		
		HttpSession session = request.getSession();
		LoginForm loginForm = (LoginForm)form;
		
		// ログインボタンを押したとき
		if(loginForm.getLogin() != null && !loginForm.getLogin().equals("")){
			// ユーザデータの取得
			MstUserDAO dao = new MstUserDAO();
			MstUser data = new MstUser();
			
			try {
				data = dao.getMstUserById(loginForm.getOperatorId());
			} catch (SQLException e) {
				return mapping.findForward("maintenance");
			}
			
			// 入力パスワードをSHA-256で暗号化
			String encryptedPassword = "";
			byte[] binary = loginForm.getPassword().getBytes();
			MessageDigest md;
			try{
				md = MessageDigest.getInstance("SHA-256");
				byte[] digest = md.digest(binary);
				
				encryptedPassword = CommonUtil.bytesToHexString(digest);
			}catch(Exception e){
				return mapping.findForward("maintenance");
			}
			
			// パスワードの有効期限のため120日前の日付を取得する
			Date d = new Date();
			Calendar cal = Calendar.getInstance();
			cal.setTime(d);
			cal.add(Calendar.DATE , -120);
			
			d = cal.getTime();
			
			if(data == null){ // ログインデータが見つからないとき
				ActionErrors errors = new ActionErrors();
				
				errors.add("operatorId", new ActionMessage("error.login.notUser"));
				// エラー内容をセット
				saveErrors(request, errors);
				// 入力画面に戻る
				return mapping.findForward("login");
			} else if(data.getLockFlag() == 1){	// ロックされているとき
				ActionErrors errors = new ActionErrors();
				
				errors.add("operatorId", new ActionMessage("error.login.lock"));
				// エラー内容をセット
				saveErrors(request, errors);
				// 入力画面に戻る
				return mapping.findForward("login");
			} else if(data.getDisabled() == 1){	// 無効化されているとき
				ActionErrors errors = new ActionErrors();
				
				errors.add("operatorId", new ActionMessage("error.login.disabled"));
				// エラー内容をセット
				saveErrors(request, errors);
				// 入力画面に戻る
				return mapping.findForward("login");
			} else if (!data.getPassword().equals(encryptedPassword)){	// パスワードが間違っているとき
				int failedCount = data.getFailedCount();
				failedCount++;
				int lockFlag = 0;
				if(failedCount > 6){
					lockFlag = 1;			
				}
				
				// ログイン情報を記録
				ExecuteLoginDAO dao2 = new ExecuteLoginDAO();
				
				try {
					dao2.executeSP(loginForm.getOperatorId(), 0, failedCount, lockFlag,request.getRemoteAddr(), session.getId());
				} catch (SQLException e) {
					return mapping.findForward("maintenance");
				}
				
				ActionErrors errors = new ActionErrors();
				
				errors.add("operatorId", new ActionMessage("error.login.errorPassword"));
				// エラー内容をセット
				saveErrors(request, errors);
				// 入力画面に戻る
				return mapping.findForward("login");
			} else if(data.getInitialPassword() == 1){ // 初期化されたパスワードのとき
				ActionErrors errors = new ActionErrors();
				
				errors.add("operatorId", new ActionMessage("error.login.initialPassword"));
				// エラー内容をセット
				saveErrors(request, errors);
				// 入力画面に戻る
				return mapping.findForward("login");
			
			} else if(data.getLastPasswordChange().before(d)){
				ActionErrors errors = new ActionErrors();
				
				errors.add("operatorId", new ActionMessage("error.login.lastPasswordChange"));
				// エラー内容をセット
				saveErrors(request, errors);
				// 入力画面に戻る
				return mapping.findForward("login");
				
			} else {
				
				// ログイン情報を記録
				ExecuteLoginDAO dao2 = new ExecuteLoginDAO();
				
				try {
					dao2.executeSP(loginForm.getOperatorId(), 1, 0, 0, request.getRemoteAddr(), session.getId());
				} catch (SQLException e) {
					return mapping.findForward("maintenance");
				}
				
				// ログイン情報オブジェクトを生成
				LoginInfo info = new LoginInfo();
				
				info.setOperatorId(data.getOperatorId());
				info.setOperatorName(data.getOperatorName());
				info.setRole(data.getRole());
				
				// セッションにログイン情報を格納
	        	session.setAttribute("loginData", info);

	        	if(info.isRoleRead() || info.isRoleWrite()){	// Read or Write
	        		return mapping.findForward("status");
	        	} else if(info.isRoleCSVDownload()){
	        		return mapping.findForward("csvDownload");	// CSVDownload
	        	} else if(info.isRoleUserManager()){
	        		return mapping.findForward("userManager");	// UserManager
	        	} else {
	        		return mapping.findForward("maintenance");
	        	}
			}
			
			
		} else {
			return mapping.findForward("login");
		}
		
	}
}
