/*

Copyright (C) 2009 NTT DATA INTELLILINK CORPORATION

This program is free software; you can redistribute it and/or
Modify it under the terms of the GNU General Public License 
as published by the Free Software Foundation, version 2.

This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied 
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.  See the GNU General Public License for more details.

 */

package jp.co.intellilink.hinemos.importtool.conf.access;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;

import javax.ejb.DuplicateKeyException;

import jp.co.intellilink.hinemos.importtool.util.CheckString;
import jp.co.intellilink.hinemos.importtool.util.Config;
import jp.co.intellilink.hinemos.importtool.util.EjbConnectionManager;
import jp.co.intellilink.hinemos.importtool.util.Messages;
import jp.co.intellilink.hinemos.importtool.util.ReadCsvFile;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.clustercontrol.accesscontrol.bean.UserListTableDefine;
import com.clustercontrol.accesscontrol.ejb.session.AccessController;
import com.clustercontrol.accesscontrol.factory.UserProperty;
import com.clustercontrol.bean.DataRangeConstant;
import com.clustercontrol.bean.Property;
import com.clustercontrol.bean.PropertyConstant;
import com.clustercontrol.bean.YesNoConstant;
import com.clustercontrol.util.PropertyUtil;

/**
 * アクセス情報をインポートするクラス<br>
 * 
 * @version 1.1.0
 * @since 1.1.0
 */
public class ImportAccess {

	// ログ出力
	private static Log log = LogFactory.getLog(ImportAccess.class);

	@SuppressWarnings("unchecked")
	private ArrayList accessList = null;

	private ArrayList<ArrayList<String>> accessInfos = null;

	/**
	 * アクセス情報をインポートする。<br>
	 */
	public void importAccess() {
		log.info(Messages.getMsg("ImportTool.Accsess.Start", new String[]{Messages.getMsg("ImportTool.Import")}));

		//アクセス情報のCSVファイルを読み込む
		accessInfos = ReadCsvFile.readCsvFile(Config.getConfig("Input.Dir.Conf") + "/ACCESS.csv");

		//ユーザリスト取得
		accessList = getAccessList();

		for(ArrayList<String> info : accessInfos){
			Property property = createAccessInfo(info);
			registerAccessInfo(property);
		}

		log.info(Messages.getMsg("ImportTool.Accsess.End", new String[]{Messages.getMsg("ImportTool.Import")}));
	}

	/**
	 * ユーザ情報を作成する。<br>
	 * 
	 * @param info アクセス情報配列
	 * @return ユーザ情報オブジェクト
	 */
	public Property createAccessInfo(ArrayList<String> info) {
		Property property = getUserProperty();

		@SuppressWarnings("unchecked")
		ArrayList propertyList = null;

		//ユーザID
		String uid = CheckString.checkLength(info.get(0), DataRangeConstant.VARCHAR_64);
		if(!uid.equals(info.get(0))){
			String[] args = { com.clustercontrol.util.Messages.getString("user.id"), "64" };
			log.error(Messages.getMsg("ImportTool.Common.2", args));
			System.exit(20);
		}
		propertyList = PropertyUtil.getProperty(property, UserProperty.UID);
		((Property)propertyList.get(0)).setValue(uid);
		//名前
		String name = CheckString.checkLength(info.get(1), DataRangeConstant.VARCHAR_1024);
		if(!name.equals(info.get(1))){
			String[] args = { com.clustercontrol.util.Messages.getString("name"), "1024" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		propertyList = PropertyUtil.getProperty(property, UserProperty.NAME);
		((Property)propertyList.get(0)).setValue(name);
		//説明
		String description = CheckString.checkLength(info.get(2), DataRangeConstant.VARCHAR_1024);
		if(!description.equals(info.get(2))){
			String[] args = { com.clustercontrol.util.Messages.getString("description"), "1024" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		propertyList = PropertyUtil.getProperty(property, UserProperty.DESCRIPTION);
		((Property)propertyList.get(0)).setValue(description);

		//リポジトリ-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.REPOSITORY_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(3))));
		//リポジトリ-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.REPOSITORY_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(4))));
		//アクセス-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.ACCESSCONTROL_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(5))));
		//アクセス-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.ACCESSCONTROL_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(6))));
		//監視管理-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(7))));
		//監視管理-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(8))));
		//ジョブ管理-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.JOBMANAGEMENT_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(9))));
		//ジョブ管理-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.JOBMANAGEMENT_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(10))));
		//ジョブ管理-実行
		propertyList = PropertyUtil.getProperty(property, UserProperty.JOBMANAGEMENT_EXECUTE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(11))));
		//性能管理-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.PERFORMANCE_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(12))));
		//性能管理-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.PERFORMANCE_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(13))));
		//性能管理-実行
		propertyList = PropertyUtil.getProperty(property, UserProperty.PERFORMANCE_EXECUTE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(14))));
		//一括制御-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.COLLECTIVERUN_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(15))));
		//一括制御-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.COLLECTIVERUN_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(16))));
		//一括制御-実行
		propertyList = PropertyUtil.getProperty(property, UserProperty.COLLECTIVERUN_EXECUTE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(17))));
		//syslog-ng監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.SYSLOGNG_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(18))));
		//syslog-ng監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.SYSLOGNG_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(19))));
		//PING監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.PING_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(20))));
		//PING監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.PING_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(21))));
		//サービス・ポート監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.PORT_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(22))));
		//サービス・ポート監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.PORT_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(23))));
		//プロセス監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.PROCESS_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(24))));
		//プロセス監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.PROCESS_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(25))));
		//SNMP監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.SNMP_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(26))));
		//SNMP監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.SNMP_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(27))));
		//SNMPTRAP監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.SNMPTRAP_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(28))));
		//SNMPTRAP監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.SNMPTRAP_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(29))));
		//SQL監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.SQL_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(30))));
		//SQL監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.SQL_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(31))));
		//エージェント監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.AGENT_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(32))));
		//エージェント監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.AGENT_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(33))));
		//HTTP監視-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.HTTP_MONITOR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(34))));
		//HTTP監視-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.HTTP_MONITOR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(35))));
		//ログ転送-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.LOG_TRANSFER_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(36))));
		//ログ転送-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.LOG_TRANSFER_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(37))));
		//カレンダ-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.CALENDAR_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(38))));
		//カレンダ-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.CALENDAR_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(39))));
		//通知-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.NOTIFY_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(40))));
		//通知-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.NOTIFY_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(41))));
		//重要度判定-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.PRIORITY_JUDGMENT_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(42))));
		//重要度判定-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.PRIORITY_JUDGMENT_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(43))));
		//メンテナンス-参照
		propertyList = PropertyUtil.getProperty(property, UserProperty.MAINTENANCE_READ);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(44))));
		//メンテナンス-設定
		propertyList = PropertyUtil.getProperty(property, UserProperty.MAINTENANCE_WRITE);
		((Property)propertyList.get(0)).setValue(
				YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(45))));

		return property;
	}

	/**
	 * ユーザ一覧に指定したユーザIDが存在するかチェックする。<br>
	 * 
	 * @param userId ユーザID
	 * @return チェック結果
	 */
	@SuppressWarnings("unchecked")
	protected ArrayList checkAccessList(String userId) {

		if(accessList instanceof ArrayList){
			Iterator itr = accessList.iterator();
			while(itr.hasNext()){
				ArrayList line = (ArrayList)itr.next();

				String id = (String)line.get(0);
				if(id.compareTo(userId) == 0)
					return line;
			}
		}

		return null;
	}

	/**
	 * アクセス情報を登録する。<br>
	 * 
	 * @param property アクセス情報
	 */
	protected void registerAccessInfo(Property property) {
		AccessController access = EjbConnectionManager.getConnectionManager().getAccessController();

		@SuppressWarnings("unchecked")
		ArrayList propertyList = null;

		propertyList = PropertyUtil.getProperty(property, UserProperty.UID);
		String userId = (String)((Property)propertyList.get(0)).getValue();

		try {
			@SuppressWarnings("unchecked")
			ArrayList line = checkAccessList(userId);
			if(line instanceof ArrayList){
				Date createTime = (Date)line.get(UserListTableDefine.CREATE_TIME);
				String createUser = (String)line.get(UserListTableDefine.CREATOR_NAME);
				propertyList = PropertyUtil.getProperty(property, UserProperty.CREATE_TIME);
				((Property)propertyList.get(0)).setValue(createTime);
				propertyList = PropertyUtil.getProperty(property, UserProperty.CREATOR_NAME);
				((Property)propertyList.get(0)).setValue(createUser);

				Object[] args = {userId};
				log.info(Messages.getMsg("ImportTool.UserID", args) + 
						" (" + Messages.getMsg("modify") + ")");

				access.modifyUser(property);
			}
			else{
				Object[] args = {userId};
				log.info(Messages.getMsg("ImportTool.UserID", args) + 
						" (" + Messages.getMsg("add") + ")");

				access.addUser(property);
			}
		} catch (DuplicateKeyException e) {
			String args[] = {userId};
			log.error(Messages.getMsg("ImportTool.Common.1", args));
			System.exit(20);
		} catch (Exception e) {
			log.error(Messages.getMsg("ImportTool.ConnectManagerFailed"), e);
			System.exit(14);
		}
	}

	/**
	 * ユーザプロパティを取得する。<br>
	 * 
	 * @return ユーザプロパティ
	 */
	protected Property getUserProperty() {

		AccessController access = EjbConnectionManager.getConnectionManager().getAccessController();

		Property property = null;
		try {
			property = access.getUserProperty("", PropertyConstant.MODE_ADD, Locale.getDefault());
		} catch (Exception e) {
			log.error(Messages.getMsg("ImportTool.ConnectManagerFailed"), e);
			System.exit(14);
		}
		return property;
	}

	/**
	 * ユーザリストを取得する。<br>
	 * 
	 * @return ユーザ一覧
	 */
	@SuppressWarnings("unchecked")
	protected ArrayList getAccessList() {

		AccessController access = EjbConnectionManager.getConnectionManager().getAccessController();

		ArrayList records = null;
		try {
			records = access.getUserList();
		} catch (Exception e) {
			log.error(Messages.getMsg("ImportTool.ConnectManagerFailed"), e);
			System.exit(14);
		}
		return records;
	}
}