//===========================================================================
// package
//===========================================================================
package jp.gr.java_conf.bugslife.action;

//===========================================================================
// import
//===========================================================================
import java.io.IOException;
import java.util.Locale;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.logging.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;
import org.apache.commons.beanutils.*;

import java.util.*;
import jp.gr.java_conf.bugslife.selections.*;
import jp.gr.java_conf.bugslife.user.*;
import jp.gr.java_conf.bugslife.bug.*;
import jp.gr.java_conf.bugslife.db.*;
import jp.gr.java_conf.bugslife.form.*;
import jp.gr.java_conf.bugslife.system.*;
import jp.gr.java_conf.bugslife.util.Converter;
import jp.gr.java_conf.bugslife.util.Assert;
import jp.gr.java_conf.bugslife.util.Varidater;
/**
 *<PRE>
 * 
 * BugDetail4Actionクラス
 *
 *</PRE>
 * @version	0.0
 * @author	鰐川 正寛
 */
public final class BugDetail4Action extends BaseAction 
{
//===========================================================================
// attributes
//===========================================================================
	/**
	 * Form
	 */
	BugDetail4Form m_form;
	/**
	 * session
	 */
	HttpSession m_session;
	/**
	 * Bug
	 */
	Bug m_bug = null;
	/**
	 * Bug
	 */
	UserInfo m_logonUser;
	/**
	 * Log
	 */
	private Log log = LogFactory.getLog(this.getClass().getName());
	/**
	 * to
	 */
	private int m_toUno;
//===========================================================================
// methods
//===========================================================================
	/**
	 * exevute
	 *
	 * @param mapping The ActionMapping used to select this instance
	 * @param actionForm The optional ActionForm bean for this request (if any)
	 * @param request The HTTP request we are processing
	 * @param response The HTTP response we are creating
	 *
	 * @exception Exception if business logic throws an exception
	 */
	public synchronized ActionForward doAction(ActionMapping mapping,
				 ActionForm form,
				 HttpServletRequest request,
				 HttpServletResponse response)
				throws Exception {
		
		ActionForward forward = null;
		/*
		 * 初期処理
		 */
		m_form = (BugDetail4Form)form;	//formの取得
		m_session = getSession(request);//sessioの取得
		m_logonUser = (UserInfo)getAttribute(m_session,"UserInfo");	//ログインユーザの取得
		m_bug = (Bug)m_session.getAttribute("bug");	//バグの取得
		
		String action = m_form.getAction();
		//debug
		log.debug(	"action =" + action + 
					" submiteType = " + m_form.getSubmitType() +
					" bno = " + m_form.getBno() +
					" bno(s) = " + (m_bug == null ? "null" : ""+m_bug.getBno()));
		
		//表示の場合
		if (action.equals("show")){
			
			//=========================
			//bugインスタンスの取得判定
			//=========================
			//セッションに無いかbnoが違う場合
			if ((m_bug == null) || (m_bug.getBno() != m_form.getBno())) {
				//バグインスタンスの取得
				m_bug = new Bug(m_form.getBno());
				//バグインスタンスのセット
				m_session.setAttribute("bug", m_bug);
			
			//そのバグが更新されていた場合
			} else {
				if (m_bug.isChanged()){
					//debug
					log.debug("is changed!");
					
					//バグインスタンスの取得
					m_bug = new Bug(m_form.getBno());
					//バグインスタンスのセット
					m_session.setAttribute("bug", m_bug);
				}
			}
			
			//入力情報セット
			PropertyUtils.copyProperties(m_form, m_bug);
			
			//showへ遷移
			forward = mapping.findForward("show");
			
		//更新の場合
		} else {
			
			//=========================
			//bugインスタンスの取得判定
			//=========================
			if ((m_bug == null) || (m_bug.getBno() != m_form.getBno())) {
				//警告！
				log.warn("unmatch bno ");
				//バグインスタンスの取得
				m_bug = new Bug(m_form.getBno());
				//バグインスタンスの再セット
				m_session.setAttribute("bug", m_bug);
			}
			
			//チェック
			ActionErrors errors = m_form.validate(mapping, request);
			if (!errors.empty()) {
				 saveErrors(request, errors);
				return (new ActionForward(mapping.getInput()));
			}
			
			try {
			
				//差分取得開始
				m_bug.startActivity();
				
				//入力情報セット
				PropertyUtils.copyProperties(m_bug, m_form);
				//入力情報タイプのセット
				m_bug.setInputType(Bug.ITYPE_DETAIL4);	
				
				//ステータスの更新
				updateStatus();
				//排他チェックも兼ねてまず更新する。
				m_bug.update(m_logonUser.getUno());		//更新
				
				//解析内容の追加
				m_bug.addText(m_form.getAddText(), m_logonUser);
				//差分の取得終了
				m_bug.endActivity();
				
				//差分を取ってくる
				Activitys act = m_bug.getActivitys();
				//メール送信不要でなければ
				if (! m_form.getDontSendMail()) {
					//メール送信
					act.sendMail(m_logonUser, request);
				}
				//履歴の出力
				act.addActivity(m_logonUser);
				
				//直前でUPDATEをしているために更新内容が変わらない場合、
				//setPersistDateでのユニーク化も聞かず、排他制御エラーとなる
				//そのうちJDBCドライバを変えて実験するが、とりあえず排他チェックを
				//はずして更新する。
				
				m_bug.update(m_logonUser.getUno(), false);		//排他制御なしの更新
				
				//successへ遷移
				forward = mapping.findForward("success");
				
			//排他例外
			} catch (ExclusionException ee) {
				//debug
				log.debug("ExclusionException", ee);
				
				Varidater.addErrors("exp.exclusion", "bug", errors);
				saveErrors(request, errors);
				return (new ActionForward(mapping.getInput()));
				
			}
		}
		// Forward control to the specified success URI
		return forward;
	}
	/**
	 * ステータスの変更
	 */
	private void updateStatus() {
		
		String submitType = m_form.getSubmitType();
		//log
		log.debug("submiteType = " + submitType);
		log.debug("updater = " + m_form.getRequestUpdater() +
				  " analyst = " + m_form.getRequestAnalyst()
		);
		
		//発行者に確認依頼
		if (submitType.equals("resolvedIssuer")) {
			m_bug.setUpdater(m_logonUser.getUno());	//修正者設定
			m_bug.setBugUpdateDate(new Date());		//修正日設定
			m_bug.setComfirmer(m_bug.getIssuer());
			
			m_bug.setStatus(Bug.STS_RESOLVED);
			
		//修正中
		} else if (submitType.equals("repaired")) {
			int updater = Integer.parseInt(m_form.getRequestUpdater());
			m_bug.setUpdater(updater);				//修正者設定
			m_bug.setBugUpdateDate(new Date());		//修正日設定
			
			m_bug.setStatus(Bug.STS_REPAIRED);
			
		//解析中
		} else if (submitType.equals("investigation")) {
			int analyst = Integer.parseInt(m_form.getRequestAnalyst());
			m_bug.setUpdater(m_logonUser.getUno());	//修正者設定
			m_bug.setBugUpdateDate(new Date());		//修正日設定
			m_bug.setAnalyst(analyst);				//解析者設定
			
			m_bug.setStatus(Bug.STS_INVESTIGATION);
			
		//そのまま
		} else if (submitType.equals("same")) {
			//なにもしない
			
		//ステータス状況変更
		} else if (submitType.equals("statusWhitebord")) {
			
			m_bug.setStatusWhitebord(m_form.getRequestStatusWhitebord());
			
		} else {
			//ここには来ないはず
			Assert.check(false, "invalid submitType type = " + submitType);
			
		}
	}
}
