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

//===========================================================================
// import
//===========================================================================
// Java core API
import java.util.*;
import java.text.*;
import org.apache.commons.logging.*;
import javax.servlet.http.*;

// API
import jp.gr.java_conf.bugslife.db.*;
import jp.gr.java_conf.bugslife.user.*;
import jp.gr.java_conf.bugslife.util.*;
import jp.gr.java_conf.bugslife.selections.*;
import jp.gr.java_conf.bugslife.system.*;

/**
 *<PRE>
 * 
 * Activitysクラス
 * 
 * ActivityのCollecitonを持つクラス
 * 
 *</PRE>
 * @version	0.0, 2001/09/10
 * @author	鰐川　正寛
 */
//===========================================================================
public class Activitys
{
//===========================================================================
// attributes
//===========================================================================
	/**
	 *	bug
	 */
	private Bug m_bug;
	/**
	 *	to
	 */
	private UserInfo m_to;
	/**
	 *	cc
	 */
	private Map m_cc = new HashMap();
	/**
	 *	AddText
	 */
	private String m_addText;
	/**
	 *	Activity
	 */
	private Map m_activitys = new HashMap();
	/**
	 *	MailElement
	 */
	private MailElements m_mail;
	
	/**
	 * Log
	 */
	private Log log = LogFactory.getLog(this.getClass().getName());
//===========================================================================
// methods
//===========================================================================
	/**
	 *	デフォルトコンストラクタ
	 *
	 */
	public Activitys()
	{
		m_activitys.clear();
		m_mail = new MailElements();
		m_cc.clear();
	}
//======================================
// Property
//======================================
	/**
	 * Activityの追加
	 * 
	 * @param activity アクティビティ
	 */
	public void add(Activity activity) {
		
		if (m_activitys.containsKey(activity.getId())) {
			//debug
			log.debug("duprecate key = " + activity.getId());
		}
		m_activitys.put(activity.getId(), activity);
	}
	/**
	 * elementsの取得
	 */
	public MailElements getMailElements() {
		return m_mail;
	}
	/**
	 * Bugのセット
	 * 
	 * @param Bug bug
	 */
	public void setBug(Bug bug)
	{
		m_bug = bug;
	}
	/**
	 * Toのセット
	 * 
	 * @param to to
	 */
	public void setTo(UserInfo to)
	{
		m_to = to;
	}
	/**
	 * ccの追加
	 * 
	 * @param cc cc
	 */
/*-------------------------------------------
	public void addCc(Collection cc)
	{
		m_cc.addAll(cc);
	}
-------------------------------------------*/
	/**
	 * 追加テキストのセット
	 * 
	 * @param addText 追加テキスト
	 */
	public void setAddText(String addText)
	{
		m_addText = addText;
	}
	/**
	 * メールの送信
	 * 
	 * @param to to
	 */
	public void sendMail(UserInfo logonUser, HttpServletRequest request) {
		
	    
		Sysconf sysconf = Sysconf.getSysconf();
		//add 2007.10.22
		//メール送信しない場合、そのままリターン
		if(sysconf.getDisableMail() == Sysconf.DISABLE_MAIL){
		    return;
		}
		
		// smtp host
		m_mail.setSmtphost(sysconf.getSmtpAdress());
		
		// FROM
		m_mail.setFrom(sysconf.getFromAdress());
		
		//messageId
		m_mail.setMessageId(m_bug.getMessageId());
		
		//subject
		StringBuffer subject = new StringBuffer();
		ProcessName pName = ProcessName.getProcessName(sysconf.getCurrentPno());
		subject.append("[" + pName.getShortName());
		//add wani 03/01/05
		//ヘッダにサブシステム名を入れる
		Subsystem ss = new Subsystem(m_bug.getSubsystem());
		subject.append(ss.getShortName());
		
		subject.append("故障#" + m_bug.getBnoString() + "]");		//[故障#0001]
		subject.append("【" + m_bug.getInputTypeString() + "】");	//【故障】
		subject.append(m_bug.getDispatchName() + " ");				//鰐川(hoge)
		subject.append(m_bug.getTitle());							//ＸＸＸができません
		m_mail.setSubject(subject.toString());
		
		//本文
		StringBuffer content = new StringBuffer();
		
		//動作
//		content.append("\n");
		content.append("この故障は");
		content.append(logonUser.getNickname());
		content.append("さんによって");
		if (m_bug.getInputType() == Bug.ITYPE_DETAIL0) {
			content.append("発行されました。\n");
		} else {
			if (m_bug.getStatus() == Bug.STS_CLOSE) {
				content.append("完了しました。\n");
			} else {
				content.append("更新されました。\n");
			}
		}
		if (m_bug.getStatus() != Bug.STS_CLOSE) {
			//ディスパッチ先未定
			content.append("ディスパッチ先は");
			if (m_bug.getDispatch() == 0) {	//未定
				content.append("未定です\n");
			} else {
				content.append(m_bug.getDispatchName() + "さんです\n");
			}
		}
		//ヘッダ
		content.append("\n");
		content.append("[番号]" + m_bug.getBnoString() + "\n");
		content.append("[表題]" + m_bug.getTitle() + "\n");
		content.append("[状態]" + m_bug.getStatusString() + "\n");
		
		//追加テキストはあったか？
		if (m_bug.isAddTextEnable()) {
/*---------------------------------------
			content.append("\n");
			
			AddText text = m_bug.getLastAddText();
			content.append("[" + text.getTextTypeString() + "]");		//[新規]
			content.append(text.getEntryUname());						//鰐川(XXX)
			content.append("(" + text.getEntryDateString() + ")\n");	//mm/dd hh:mm
			content.append("\n");
---------------------------------------*/
			AddText text = m_bug.getLastAddText();
			content.append("[" + text.getTextTypeString() + "]");		//[新規]
			content.append("\n");
			content.append(text.getContent());							//内容
			content.append("\n");
		}
		content.append("\n");
		content.append("---------変更内容------------\n");
		if((m_activitys != null) && (m_activitys.size() > 0)){
			//メール出力項目を元にActivityを出力する
			//[nnn ]xxxxの形式。
			//[]の長さが不揃いになると見づらいので、nnnの最大長を取って
			//インデントしながら値を出力する。
			
			//出力項目名の最大長を求める
			int maxLen = 0;
			int nameLen = 0;
			for (int i = 0; i < BugItem.MAIL_ITEM_SEQ.length; i++) {
				if (m_activitys.containsKey(BugItem.MAIL_ITEM_SEQ[i])) {
					Activity act = (Activity)m_activitys.get(BugItem.MAIL_ITEM_SEQ[i]);
					nameLen = act.getName().getBytes().length;		//バイト数で数える
					maxLen = (maxLen < nameLen ? nameLen : maxLen);
				}
			}
			//フォーマットしながら項目を出力する
			for (int i = 0; i < BugItem.MAIL_ITEM_SEQ.length; i++) {
				if (m_activitys.containsKey(BugItem.MAIL_ITEM_SEQ[i])) {
					Activity act = (Activity)m_activitys.get(BugItem.MAIL_ITEM_SEQ[i]);
					content.append("[" + 
									act.getName() + 
									//項目名を
									Converter.space(maxLen-act.getName().getBytes().length) + 
									"]");
					content.append(act.toStringForMail() + "\n");
				}
			}
		}
		content.append("\n");
		
		//メールからのログイン用にURLを生成する。
		
		String baseURL = request.getScheme() + 
						"://" + request.getServerName() + 
						":" + 
						request.getServerPort() + 
						request.getContextPath();
		
		content.append("URL:");
		content.append(baseURL + "/logon.do?bno=" + m_bug.getBno() + "\n");
		content.append("\n");
		
		//メールの宛先を作る
		setMailAdress(logonUser, content);
		
		content.append("\n");
		content.append("---\n");
		content.append(m_mail.getFrom());
		
		m_mail.setBody(content.toString());
		
		/**
		 *メールの送信
		*/
		try {
			MailSender.send(m_mail);
			
		} catch (Exception e) {
			log.error("mail send error", e);
		}
		
		m_bug.setMessageId(m_mail.getMessageId());
	}
	/**
	 * メールアドレスの生成
	 */
	private void setMailAdress(UserInfo logonUser, StringBuffer content) {
		
		
		//メールオブジェクトへセット
		
		//----------------------------
		// fromの生成
		//----------------------------
		//emailにはセットしない
		content.append("from:" + logonUser.getNickname() + "\n");	//本文
		
		//----------------------------
		// toの生成
		//----------------------------
		m_to = m_bug.getDispatchUser();		//担当者取得
		if (m_to != null) {
			m_mail.addTo(m_to);
			content.append("to  :" + m_to.getNickname() + "\n");	//本文
		}
		
		//----------------------------
		// ccの生成
		//----------------------------
		//fromをccに加える
		m_cc.put(logonUser.getEmail(), logonUser);
		
		//bugの持っているCCを追加
		Collection ccs = m_bug.getCc();
		if (ccs != null) {
			Iterator ite = ccs.iterator();
			while(ite.hasNext()){
				Cc cc = (Cc)ite.next();
				UserInfo user = UserInfo.getUser(cc.getUno());
				m_cc.put(user.getEmail(), user);
			}
		}
		//関係者をCCに加える
		//発行者
		if (m_bug.getIssuer() != 0) {
			UserInfo user = UserInfo.getUser(m_bug.getIssuer());
			m_cc.put(user.getEmail(), user);
		}
		//承認者
		if (m_bug.getAuther() != 0) {
			UserInfo user = UserInfo.getUser(m_bug.getAuther());
			m_cc.put(user.getEmail(), user);
		}
		//解析者
		if (m_bug.getAnalyst() != 0) {
			UserInfo user = UserInfo.getUser(m_bug.getAnalyst());
			m_cc.put(user.getEmail(), user);
		}
		//修正者
		if (m_bug.getUpdater() != 0) {
			UserInfo user = UserInfo.getUser(m_bug.getUpdater());
			m_cc.put(user.getEmail(), user);
		}
		//確認者
		if (m_bug.getComfirmer() != 0) {
			UserInfo user = UserInfo.getUser(m_bug.getComfirmer());
			m_cc.put(user.getEmail(), user);
		}
		
		//そのメールタイプを購読している人をCCに追加
		Collection ccUsers = null;
		switch(m_bug.getInputType()) {
		case Bug.ITYPE_DETAIL0 :		//発行
			ccUsers = UserInfo.getUserForMailType(UserInfo.MAIL_DETAIL0);
			break;
		case Bug.ITYPE_DETAIL1 :		//故障
			ccUsers = UserInfo.getUserForMailType(UserInfo.MAIL_DETAIL1);
			break;
		case Bug.ITYPE_DETAIL2 :		//方針
			ccUsers = UserInfo.getUserForMailType(UserInfo.MAIL_DETAIL2);
			break;
		case Bug.ITYPE_DETAIL3 :		//解析
			ccUsers = UserInfo.getUserForMailType(UserInfo.MAIL_DETAIL3);
			break;
		case Bug.ITYPE_DETAIL4 :		//処置
			ccUsers = UserInfo.getUserForMailType(UserInfo.MAIL_DETAIL4);
			break;
		case Bug.ITYPE_DETAIL5 :		//確認
			ccUsers = UserInfo.getUserForMailType(UserInfo.MAIL_DETAIL5);
			break;
		}
		
		if (ccUsers != null) {
			Iterator ite = ccUsers.iterator();
			while(ite.hasNext()){
				UserInfo user = (UserInfo)ite.next();
				m_cc.put(user.getEmail(), user);
			}
		}
		//toに入ってる人はccから削除する
		if (m_to != null) {
			m_cc.remove(m_to.getEmail());		//to
		}
		
		//CCのセット
		Iterator ite2 = m_cc.keySet().iterator();
		int i = 0;
		while(ite2.hasNext()){
			String email = (String)ite2.next();
			UserInfo user = (UserInfo)m_cc.get(email);
			
			m_mail.addCc(user);				//メールに追加
			
			//CCの内容生成
			if (i == 0) {
				content.append("cc  :");
			} else if( (i % 3) == 0) {
				content.append("\n     ");
			} else {
				content.append(", ");
			}
			content.append(user.getNickname());
			i++;
			
		}
		
	}
	/**
	 * 履歴の追加
	 * 
	 * @param to to
	 */
	public void addActivity(UserInfo logonUser) {
		
		//履歴があるか？
		if (m_activitys.size() != 0) {
			ArrayList list = new ArrayList();
			//履歴取得項目リストと照らし合わせながらコレクションを作っていく
			for (int i = 0; i < BugItem.MAIL_ITEM_SEQ.length; i++) {
				//あり？
				if (m_activitys.containsKey(BugItem.MAIL_ITEM_SEQ[i])) {
					Activity act = (Activity)m_activitys.get(BugItem.MAIL_ITEM_SEQ[i]);
/*-------------------------
					//注意
					//履歴の場合は、古い値が無ければ履歴を取得しない。
					//メールの場合はWeb代わりに見るので、旧値があってもなくても出すが
					//履歴の場合は変わったところしか見たくないので、本当の差分のみ出す
					//ただし、新値が空になった（指定を取り消した）場合は履歴として
					//残すものとする。
					if (act.getOldValueString().length() != 0) {
-------------------------*/
						//追加
						list.add(act);
/*-------------------------
					}
-------------------------*/
				}
			}
			//履歴を出力
			BugActivity.addBugActivity(list, m_bug.getBno(), logonUser.getUno());
		}
		
	}
//===========================================================================
// methods
//===========================================================================
	/**
	 *	クラス情報
	 */
	public String toString()
	{
		StringBuffer sb = new StringBuffer();
		sb.append("--- [ACTIVITYS] --- \n");
		if((m_activitys != null) && (m_activitys.size() > 0)){
			Collection values = m_activitys.values();
			Iterator ite = values.iterator();
			while(ite.hasNext()) {
				Activity act = (Activity)ite.next();
				sb.append(act.toStringForMail() + "\n");
			}
		} else {
			sb.append("no activity\n");
		}
		sb.append("--- [ACTIVITYS] --- \n");
		return sb.toString();
	}
}