/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.mail;

import org.opengion.fukurou.system.OgRuntimeException ;		// 6.4.2.0 (2016/01/29)
// import java.util.Map;
// import java.util.TreeMap;
import java.util.concurrent.ConcurrentMap;							// 6.4.3.3 (2016/03/04)
import java.util.concurrent.ConcurrentSkipListMap;					// 6.4.3.3 (2016/03/04)

import org.opengion.hayabusa.db.DBColumn;
import org.opengion.hayabusa.db.DBTableModelUtil;
import org.opengion.hayabusa.resource.ResourceManager;
import org.opengion.hayabusa.db.DBTableModel;

/**
 * タグ mailSender2 による送信を行う際に利用するメール送信マネージャの処理クラスです。
 * タグ mailSender2 よりパラメータマップを受取って、メール文の合成、送信を行います。
 * バッチ送信する場合と共通する部分はスーパークラス DefaultMailManager に実装していますが、
 * タグ独自ロジックの部分は本クラスより実装を行っています。
 * 独自ロジックはセッションから取得した宛先テーブルにより宛先マップを作成、セッションから取得したメール
 * 文により送信を行うロジックとあります。
 *
 * @og.group メールモジュール
 *
 * @version  4.0
 * @author   Sen.Li
 * @since    JDK1.6
 */
public class MailManager_DIRECT extends DefaultMailManager {

	// 6.4.1.1 (2016/01/16) names → NAMES refactoring
	private static final String[] NAMES	= { "DST_ID", "GROUP_ID", "GROUP_NAME", "DST_NAME", "DST_ADDR", "DST_KBN", "FGJ_MAIL" };
	private static final int IDX_DST_ID 	= 0;
	private static final int IDX_FGJ_MAIL 	= 6;
	private ResourceManager resource		;

	/**
	 * デフォルトコンストラクター
	 *
	 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
	 */
	public MailManager_DIRECT() { super(); }		// これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。

	/**
	 * action="SEND"の時にこのメソッドが呼ばれます。
	 * セッションから取得した宛先テーブルにより宛先マップを作成します。
	 * まだ、action="CHECK"の時に、確認画面から添付ファイルを追加するケースがあるため、
	 * パラメータを再読込を行います。そして、action="SEND"の時に添付ファイルを送信します。
	 *
	 * @og.rev 6.0.3.0 (2014/11/13) Ver6用キーワード変更
	 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
	 *
	 * @param	params	パラメータのマップ
	 * @param	table	DBTableModelオブジェクト
	 *
	 */
//	public void create( final Map<String, String> params, final DBTableModel table ){
	public void create( final ConcurrentMap<String, String> params, final DBTableModel table ){
		// 5.6.6.0 (2013/07/05) host指定対応
		final MailPattern mailObj = new MailPattern( params );
		setHost(mailObj.getHost());
		setPort(mailObj.getSmtpPort());
		setAuthType(mailObj.getAuthType());		// 6.0.3.0 (2014/11/13) Ver6用キーワード変更
		setAuthUser(mailObj.getAuthUser());
		setAuthPass(mailObj.getAuthPass());

		setInitParams( params );
		setAttachFiles(   params.get( "ATTACH1" )
		        		, params.get( "ATTACH2" )
		                , params.get( "ATTACH3" )
		                , params.get( "ATTACH4" )
		                , params.get( "ATTACH5" ));
//		final Map <String, String[]> dstMap = makeMailDstMap( table );
		final ConcurrentMap <String, String[]> dstMap = makeMailDstMap( table );			// 6.4.3.3 (2016/03/04)
		setMailDstMap( dstMap );
	}

	/**
	 * 画面に各宛先の送信状況を表示するために、送信の宛先マップに基づいてテーブルモデルを作成します。
	 * 作成されたテーブルモデルを指定されるスコープに入れます。
	 *
	 * @og.rev 5.1.9.0 (2010/08/01) keySet() → entrySet() に変更
	 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
	 * @og.rev 6.4.3.4 (2016/03/11) forループを、forEach メソッドに置き換えます。
	 *
	 * @return	宛先マップに基づいたテーブルモデル
	 */
	public DBTableModel makeDstTable(){
//		final Map<String, String[]> mailDst = getMailDstMap();
		final ConcurrentMap<String, String[]> mailDst = getMailDstMap();
		DBTableModel table;
		final int numberOfColumns = NAMES.length;

		table = DBTableModelUtil.newDBTable();
		table.init( numberOfColumns );
		setTableDBColumn( table, NAMES );

		// 5.1.9.0 (2010/08/01) keySet() → entrySet() に変更
		// 6.4.3.4 (2016/03/11) forループを、forEach メソッドに置き換えます。
		mailDst.values().forEach( v -> table.addColumnValues( v ) );
//		for( final Map.Entry<String, String[]> en : mailDst.entrySet() ) {
//			table.addColumnValues( en.getValue() );
//		}

		return table;
	}

	/**
	 * リソースマネージャーをセットします。
	 * これは、言語(ロケール)に応じた DBColumn をあらかじめ設定しておく為に
	 * 必要です。
	 * リソースマネージャーが設定されていない、または、所定のキーの DBColumn が
	 * リソースに存在しない場合は、内部で DBColumn オブジェクトを作成します。
	 *
	 * @param  res リソースマネージャー
	 */
	// 注意：この resource は、実質利用されていません。
	public void setResourceManager( final ResourceManager res ) {
		resource = res;
	}

	/**
	 * DBColumn オブジェクトをテーブルモデルに設定します。
	 *
	 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
	 *
	 * @param	table	DBTableModelオブジェクト
	 * @param	names	カラム名配列(可変長引数)
	 */
	// 注意：この dbColumn は、実質利用されていません。
	protected void setTableDBColumn( final DBTableModel table, final String... names ) {
		// 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
		if( resource == null ) {
			final String errMsg = "#setResourceManager(ResourceManager)を先に実行しておいてください。" ;
			throw new OgRuntimeException( errMsg );
		}

		for( int i=0; i<names.length; i++ ) {
			final DBColumn clm = resource.makeDBColumn( names[i] );
			table.setDBColumn( i,clm );
		}
	}

	/**
	 * セッションから取得した宛先テーブルにより宛先マップを作成します。
	 * 宛先テーブルの各レコードに対して、"送信待ち"となっているレコードのみ宛先マップに入れるようにしています。
	 *
	 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
	 *
	 * @param	table	セッションから取得した宛先テーブル
	 *
	 * @return	宛先マップ
	 */
//	private Map<String, String[]> makeMailDstMap( final DBTableModel table ){
	private ConcurrentMap<String, String[]> makeMailDstMap( final DBTableModel table ){
//		final Map<String, String[]> dstMap = new TreeMap<>();
		final ConcurrentMap<String, String[]> dstMap = new ConcurrentSkipListMap<>();		// 6.4.3.3 (2016/03/04)
		final int rowCount = table.getRowCount();
		final int colCount = NAMES.length;
		for( int i=0; i<rowCount; i++ ) {
			String[] tmpDst = new String[colCount];
			if( DefaultMailManager.FGJ_SEND_WAIT.equals( table.getValue( i, IDX_FGJ_MAIL ) ) ) {
				for( int j=0; j<colCount; j++ ) {
					tmpDst[j] = table.getValue( i, j );
				}
				if( tmpDst[IDX_DST_ID] != null ) {											// 6.4.3.3 (2016/03/04) not null 制限
					dstMap.put( tmpDst[IDX_DST_ID], tmpDst );
				}
			}
		}

		return dstMap;
	}
}
