/*

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.repository;

import java.util.ArrayList;

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

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

import com.clustercontrol.bean.YesNoConstant;
import com.clustercontrol.repository.bean.NodeHostnameInfo;
import com.clustercontrol.repository.bean.NodeInfo;
import com.clustercontrol.repository.ejb.session.RepositoryController;

/**
 * ノード情報をインポートするクラス<br>
 * 
 * @version 1.0.0
 * @since 1.0.0
 */
public class ImportNode {

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

	private ArrayList<NodeInfo> nodeList = null;

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

	/**
	 * ノード情報をインポートする。<br>
	 */
	public void importNode() {
		log.info(Messages.getMsg("Node.Start", new String[]{Messages.getMsg("ImportTool.Import")}));

		//ノード情報のCSVファイルを読み込む
		nodeInfos = ReadCsvFile.readCsvFile(Config.getConfig("Import.Dir") + "/NODE.csv");

		//ノードリスト取得
		nodeList = getNodeList();

		for(ArrayList<String> info : nodeInfos){
			NodeInfo node = createNodeInfo(info);
			registerNodeInfo(node);
		}

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

	/**
	 * ノード情報を作成する。<br>
	 * 
	 * @param info ノード情報配列
	 * @return ノード情報オブジェクト
	 */
	public NodeInfo createNodeInfo(ArrayList<String> info) {
		NodeInfo node = new NodeInfo();

		//ファシリティID
		String id = CheckString.checkLength(info.get(0), 64);
		if(!id.equals(info.get(0))){
			String[] args = { com.clustercontrol.util.Messages.getString("facility.id"), "64" };
			log.error(Messages.getMsg("ImportTool.Common.2", args));
			System.exit(20);
		}
		node.setFacilityId(id);
		//ファシリティ名
		String name = CheckString.checkLength(info.get(1), 128);
		if(!name.equals(info.get(1))){
			String[] args = { com.clustercontrol.util.Messages.getString("facility.name"), "128" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setFacilityName(name);
		//説明
		String description = CheckString.checkLength(info.get(2), 256);
		if(!description.equals(info.get(2))){
			String[] args = { com.clustercontrol.util.Messages.getString("description"), "256" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setDescription(description);
		//プラットフォーム
		String platformFamily = CheckString.checkLength(info.get(3), 128);
		if(!platformFamily.equals(info.get(3))){
			String[] args = { com.clustercontrol.util.Messages.getString("platform.family.name"), "128" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setPlatformFamily(platformFamily);
		//H/Wタイプ
		String hwType = CheckString.checkLength(info.get(4), 128);
		if(!hwType.equals(info.get(4))){
			String[] args = { com.clustercontrol.util.Messages.getString("hardware.type"), "128" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setHardwareType(hwType);
		//画面アイコンイメージ
		String iconImage = CheckString.checkLength(info.get(5), 256);
		if(!iconImage.equals(info.get(5))){
			String[] args = { com.clustercontrol.util.Messages.getString("icon.image"), "256" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setIconImage(iconImage);
		//管理対象
		node.setValid(YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(6))));
		//SNMPポート番号
		try {
			node.setSnmpPort(Integer.parseInt(info.get(7)));
		} catch (NumberFormatException e) {
		}
		//SNMPコミュニティ名
		String snmpCommunity = CheckString.checkLength(info.get(8), 64);
		if(!snmpCommunity.equals(info.get(8))){
			String[] args = { com.clustercontrol.util.Messages.getString("community.name"), "64" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setSnmpCommunity(snmpCommunity);
		//SNMPバージョン
		String snmpVersion = CheckString.checkLength(info.get(9), 8);
		if(!snmpVersion.equals(info.get(9))){
			String[] args = { com.clustercontrol.util.Messages.getString("snmp.version"), "8" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setSnmpVersion(snmpVersion);
		//SNMPタイムアウト
		try {
			node.setSnmpTimeout(Integer.parseInt(info.get(10)));
		} catch (NumberFormatException e) {
		}
		//SNMPリトライ回数
		try {
			node.setSnmpRetryCount(Integer.parseInt(info.get(11)));
		} catch (NumberFormatException e) {
		}
		//SNMPプロキシ
		String snmpProxy = CheckString.checkLength(info.get(12), 512);
		if(!snmpProxy.equals(info.get(12))){
			String[] args = { com.clustercontrol.util.Messages.getString("snmp.proxy"), "512" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setSnmpProxy(snmpProxy);
		//WBEM接続ユーザ名
		String wbemUser = CheckString.checkLength(info.get(13), 64);
		if(!wbemUser.equals(info.get(13))){
			String[] args = { com.clustercontrol.util.Messages.getString("wbem.user"), "64" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setWbemUser(wbemUser);
		//WBEM接続ユーザパスワード
		String wbemUserPassword = CheckString.checkLength(info.get(14), 64);
		if(!wbemUserPassword.equals(info.get(14))){
			String[] args = { com.clustercontrol.util.Messages.getString("wbem.user.password"), "64" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setWbemUserPassword(wbemUserPassword);
		//WBEMポート番号
		try {
			node.setWbemPort(Integer.parseInt(info.get(15)));
		} catch (NumberFormatException e) {
		}
		//WBEMプロトコル
		String wbemProtocol = CheckString.checkLength(info.get(16), 32);
		if(!wbemProtocol.equals(info.get(16))){
			String[] args = { com.clustercontrol.util.Messages.getString("wbem.protocol"), "32" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setWbemProtocol(wbemProtocol);
		//WBEMタイムアウト
		try {
			node.setWbemTimeout(Integer.parseInt(info.get(17)));
		} catch (NumberFormatException e) {
		}
		//WBEMリトライ回数
		try {
			node.setWbemRetryCount(Integer.parseInt(info.get(18)));
		} catch (NumberFormatException e) {
		}
		//DHCPクライアント
		node.setDhcpClient(YesNoConstant.typeToBoolean(YesNoConstant.stringToType(info.get(19))));
		//IPアドレス種別
		try {
			node.setIpAddressType(Integer.parseInt(info.get(20)));
		} catch (NumberFormatException e) {
		}
		//IPアドレスバージョン
		try {
			node.setIpAddressVersion(Integer.parseInt(info.get(21)));
		} catch (NumberFormatException e) {
		}
		//IPアドレスV4
		String ipAddressV4 = CheckString.checkLength(info.get(22), 16);
		if(!ipAddressV4.equals(info.get(22))){
			String[] args = { com.clustercontrol.util.Messages.getString("ip.address.v4"), "16" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setIpAddressV4(ipAddressV4);
		//IPアドレスV6
		String ipAddressV6 = CheckString.checkLength(info.get(23), 40);
		if(!ipAddressV6.equals(info.get(23))){
			String[] args = { com.clustercontrol.util.Messages.getString("ip.address.v6"), "40" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setIpAddressV6(ipAddressV6);
		//ホスト名
		String hostname = CheckString.checkLength(info.get(24), 128);
		if(!hostname.equals(info.get(24))){
			String[] args = { com.clustercontrol.util.Messages.getString("host.name"), "128" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		ArrayList<NodeHostnameInfo> hostnames = new ArrayList<NodeHostnameInfo>();
		hostnames.add(new NodeHostnameInfo(hostname));
		node.setNodeHostnameInfo(hostnames);
		//ノード名
		String nodeName = CheckString.checkLength(info.get(25), 128);
		if(!nodeName.equals(info.get(25))){
			String[] args = { com.clustercontrol.util.Messages.getString("node.name"), "128" };
			log.warn(Messages.getMsg("ImportTool.Common.2", args));
		}
		node.setNodeName(nodeName);
		//OS名
		if(info.size() >= 27){
			String osName = CheckString.checkLength(info.get(26), 256);
			if(!osName.equals(info.get(26))){
				String[] args = { com.clustercontrol.util.Messages.getString("os.name"), "256" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setOsName(osName);
		}
		//OSリリース
		if(info.size() >= 28){
			String osRelease = CheckString.checkLength(info.get(27), 256);
			if(!osRelease.equals(info.get(27))){
				String[] args = { com.clustercontrol.util.Messages.getString("os.release"), "256" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setOsRelease(osRelease);
		}
		//OSバージョン
		if(info.size() >= 29){
			String osVersion = CheckString.checkLength(info.get(28), 256);
			if(!osVersion.equals(info.get(28))){
				String[] args = { com.clustercontrol.util.Messages.getString("os.version"), "256" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setOsVersion(osVersion);
		}
		//文字セット
		if(info.size() >= 30){
			String osVersion = CheckString.checkLength(info.get(29), 16);
			if(!osVersion.equals(info.get(29))){
				String[] args = { com.clustercontrol.util.Messages.getString("character.set"), "16" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setOsVersion(osVersion);
		}
		//仮想化ノード種別
		if(info.size() >= 31){
			String virtualizationNodeType = CheckString.checkLength(info.get(30), 64);
			if(!virtualizationNodeType.equals(info.get(30))){
				String[] args = { com.clustercontrol.util.Messages.getString("virtualization.node.type"), "64" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setVirtualizationNodeType(virtualizationNodeType);
		}
		//仮想化管理ノード
		if(info.size() >= 32){
			String vmManagementNode = CheckString.checkLength(info.get(31), 64);
			if(!vmManagementNode.equals(info.get(31))){
				String[] args = { com.clustercontrol.util.Messages.getString("vm.management.node"), "64" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setVmManagementNode(vmManagementNode);
		}
		//仮想マシンINDEX
		if(info.size() >= 33){
			try {
				node.setVmIndex(Integer.parseInt(info.get(32)));
			} catch (NumberFormatException e) {
			}
		}
		//仮想マシン名
		if(info.size() >= 34){
			String vmName = CheckString.checkLength(info.get(33), 128);
			if(!vmName.equals(info.get(33))){
				String[] args = { com.clustercontrol.util.Messages.getString("vm.name"), "128" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setVmName(vmName);
		}
		//仮想化ソリューション
		if(info.size() >= 35){
			String virtualizationSolution = CheckString.checkLength(info.get(34), 256);
			if(!virtualizationSolution.equals(info.get(34))){
				String[] args = { com.clustercontrol.util.Messages.getString("virtualization.solution"), "256" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setVirtualizationSolution(virtualizationSolution);
		}
		//仮想マシンID
		if(info.size() >= 36){
			String vmId = CheckString.checkLength(info.get(35), 256);
			if(!vmId.equals(info.get(35))){
				String[] args = { com.clustercontrol.util.Messages.getString("vm.id"), "256" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setVmId(vmId);
		}
		//仮想化ソフト接続ユーザ
		if(info.size() >= 37){
			String vmUser = CheckString.checkLength(info.get(36), 64);
			if(!vmUser.equals(info.get(36))){
				String[] args = { com.clustercontrol.util.Messages.getString("vm.user"), "64" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setVmUser(vmUser);
		}
		//仮想化ソフト接続ユーザパスワード
		if(info.size() >= 38){
			String vmUserPassword = CheckString.checkLength(info.get(37), 64);
			if(!vmUserPassword.equals(info.get(37))){
				String[] args = { com.clustercontrol.util.Messages.getString("vm.userpassword"), "64" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setVmUserPassword(vmUserPassword);
		}
		//仮想化ソフト接続プロトコル
		if(info.size() >= 39){
			String vmProtocol = CheckString.checkLength(info.get(38), 32);
			if(!vmProtocol.equals(info.get(38))){
				String[] args = { com.clustercontrol.util.Messages.getString("vm.protocol"), "32" };
				log.warn(Messages.getMsg("ImportTool.Common.2", args));
			}
			node.setVmProtocol(vmProtocol);
		}
		
		return node;
	}

	/**
	 * ノード一覧に指定したファシリティIDが存在するかチェックする。<br>
	 * 
	 * @param facilityId ファシリティID
	 * @return チェック結果
	 */
	protected NodeInfo checkNodeList(String facilityId) {
		for(NodeInfo node : nodeList){
			if(node.getFacilityId().compareTo(facilityId) == 0)
				return node;
		}

		return null;
	}

	/**
	 * ノード情報を登録する。<br>
	 * 
	 * @param node ノード情報
	 */
	protected void registerNodeInfo(NodeInfo node) {

		RepositoryController repository = EjbConnectionManager.getConnectionManager().getRepositoryController();

		String facilityId = node.getFacilityId();

		try {
			NodeInfo line = checkNodeList(facilityId);
			if(line instanceof NodeInfo){
				node.setCreateDatetime(line.getCreateDatetime());
				node.setCreateUserId(line.getCreateUserId());
				node.setCreateUserId(line.getCreateUserId());
				
				node.setNodeDeviceInfo(line.getNodeDeviceInfo());
				node.setNodeFilesystemInfo(line.getNodeFilesystemInfo());
				node.setNodeNoteInfo(line.getNodeNoteInfo());
				
				Object[] args = {facilityId};
				log.info(Messages.getMsg("FacilityID", args) + 
						" (" + Messages.getMsg("modify") + ")");

				repository.modifyNode(node);
			}
			else{
				Object[] args = {facilityId};
				log.info(Messages.getMsg("FacilityID", args) + 
						" (" + Messages.getMsg("add") + ")");

				repository.addNode(node);
			}
//		} catch (DuplicateKeyException e) {
//			String args[] = {facilityId};
//			log.error(Messages.getMsg("ImportTool.Common.1", args));
//			System.exit(20);
		} catch (Exception e) {
			log.error(Messages.getMsg("ConnectManagerFailed"), e);
			System.exit(14);
		}
	}

	/**
	 * ファシリティリストを取得する。<br>
	 * 
	 * @return ファシリティ一覧
	 */
	protected ArrayList<NodeInfo> getNodeList() {

		RepositoryController repository = EjbConnectionManager.getConnectionManager().getRepositoryController();

		ArrayList<NodeInfo> nodeList = new ArrayList<NodeInfo>();
		try {
			ArrayList<String> records = repository.getNodeFacilityIdList();
			for(String facilityId : records){
				NodeInfo node = repository.getNode(facilityId);
				nodeList.add(node);
			}
		} catch (Exception e) {
			log.error(Messages.getMsg("ConnectManagerFailed"), e);
			System.exit(14);
		}
		return nodeList;
	}
}