package org.postgresforest.tool.commandline.action;

import java.util.ArrayList;
import java.util.Iterator;

import org.postgresforest.tool.action.ConfigAction;
import org.postgresforest.tool.bean.ConfigInfo;
import org.postgresforest.tool.db.GSCdata;
import org.postgresforest.tool.util.CommandParser;
import org.postgresforest.tool.util.MessagesCommandLine;

/**
 * コンフィグレーションへのコマンドラインツール用のアクションを提供するクラス
 */
public class ConfigActions {
	private static final String CFGNAME_OPTION_NAME = "cfgname"; //$NON-NLS-1$
	private static final String DESCRIPTION_OPTION_NAME = "descript"; //$NON-NLS-1$
	private static final String REFRESH_OPTION_NAME = "refresh"; //$NON-NLS-1$
	private static final String RETRYCOUNT_OPTION_NAME = "retry"; //$NON-NLS-1$
	private static final String DETECTTIMEOUT_OPTION_NAME = "timeout"; //$NON-NLS-1$
	private static final String DISTRIBUTION_OPTION_NAME = "dist"; //$NON-NLS-1$
	private static final String PARTMODE_OPTION_NAME = "pmode"; //$NON-NLS-1$
	private static final String SYNCMODE_OPTION_NAME = "smode"; //$NON-NLS-1$
	private static final String PARTMODE_PART = "0"; //$NON-NLS-1$
	private static final String PARTMODE_NOPART = "1"; //$NON-NLS-1$
	private static final String SYNCMODE_SYNC = "1"; //$NON-NLS-1$
	private static final String SYNCMODE_NOSYNC = "0"; //$NON-NLS-1$

	/**
	 * コンフィグレーションの作成
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 */	
	public void create(CommandParser cp, GSCdata gsc) {
		//Config名取得
		String cfgName = (String)cp.getConfigName().get(0);
		
		ConfigInfo configInfo = new ConfigInfo();
		configInfo.setConfigId(cfgName);

		if(gsc == null)
			return;
		
		ConfigAction addConfig = new ConfigAction(gsc);
		try {
			if(addConfig.add(configInfo)){
				System.out.println(MessagesCommandLine.getString("cui.message.config.create", new Object[] {cfgName})); //$NON-NLS-1$				
				return;
			}
		} catch (Exception e) {
		}
		System.out.println(MessagesCommandLine.getString("cui.error.config.create", new Object[] {cfgName})); //$NON-NLS-1$
	}
	
	/**
	 * コンフィグレーションの削除
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 */	
	public void drop(CommandParser cp, GSCdata gsc) {
		String id = (String)cp.getConfigName().get(0);

		if(id.equals(ConfigInfo.FOREST_DEFAULT_CONFIG)){
		    
		    System.err.println(MessagesCommandLine.getString("errors.gsc.config.del.default")); //$NON-NLS-1$
		    return;
		}else if(id != ""){ //$NON-NLS-1$
			//削除

			ConfigAction configAction = new ConfigAction(gsc);
			try {
				if(configAction.del(id)){
					System.out.println(MessagesCommandLine.getString("cui.message.config.drop", new Object[] {id})); //$NON-NLS-1$
					return;
				}
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		System.out.println(MessagesCommandLine.getString("cui.error.config.drop", new Object[] {id})); //$NON-NLS-1$
	}

	/**
	 * コンフィグレーションの項目設定
	 * @param gsc GSCヘの接続情報
	 */	
	public void set(CommandParser cp, GSCdata gsc) {
		// Config名の取得
		String id =  (String)cp.getConfigName().get(0);
		
		// ConfigInfoオブジェクトの取得
		ConfigAction configAction = new ConfigAction(gsc);
		ConfigInfo configInfo = null;
		try {
			configInfo = configAction.get(id);
		} catch (Exception e1) {
			// TODO 自動生成された catch ブロック
			System.out.println(MessagesCommandLine.getString("cui.error.config.set", new Object[] {id})); //$NON-NLS-1$
			e1.printStackTrace();
			return;
		}

		// Configオプションの取得/設定
		// Configパラメータの取得
		ArrayList paramNames = cp.getParamName();
		ArrayList paramValues = cp.getParamValue();
		for (int i=0; i<paramNames.size(); i++) {
			String paramName = (String)paramNames.get(i);
			if (paramName.compareToIgnoreCase(CFGNAME_OPTION_NAME) == 0) {
				String cfgName = (String)paramValues.get(i);
				configInfo.setConfigId(cfgName);
			} else if (paramName.compareToIgnoreCase(DESCRIPTION_OPTION_NAME) == 0) {
				String descript = (String)paramValues.get(i);
				configInfo.setDescription(descript);
			} else if (paramName.compareToIgnoreCase(REFRESH_OPTION_NAME) == 0) {
				long refresh = Long.parseLong((String)paramValues.get(i));
				configInfo.setCacheReflesh(refresh);
			} else if (paramName.compareToIgnoreCase(RETRYCOUNT_OPTION_NAME) == 0) {
				long retry = Long.parseLong((String)paramValues.get(i));
				configInfo.setRetryCount(retry);
			} else if (paramName.compareToIgnoreCase(DETECTTIMEOUT_OPTION_NAME) == 0) {
				long timeout = Long.parseLong((String)paramValues.get(i));
				configInfo.setDefectTimeout(timeout);
			} else if (paramName.compareToIgnoreCase(DISTRIBUTION_OPTION_NAME) == 0) {
				int dist = Integer.parseInt((String)paramValues.get(i));
				configInfo.setDistributedCon(dist);
			} else if (paramName.compareToIgnoreCase(PARTMODE_OPTION_NAME) == 0) {
				String pmode = (String)paramValues.get(i);
				boolean isNoPart = false;
				if (pmode.equals(PARTMODE_NOPART)) {
					isNoPart = true;
				}
				configInfo.setPertitionMode(isNoPart);
			} else if (paramName.compareToIgnoreCase(SYNCMODE_OPTION_NAME) == 0) {
				String smode = (String)paramValues.get(i);
				boolean isSync = false;
				if (smode.equals(SYNCMODE_SYNC)) {
					isSync = true;
				}
				configInfo.setSyncMode(isSync);
			} else {
				System.out.println(MessagesCommandLine.getString("cui.error.commandparser.param.invalid")); //$NON-NLS-1$
				return;
			}
		}

		// Configの実行
		try {
			if(configAction.mod(id, configInfo)){
				System.out.println(MessagesCommandLine.getString("cui.message.config.set", new Object[] {id})); //$NON-NLS-1$
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(MessagesCommandLine.getString("cui.error.config.set", new Object[] {id})); //$NON-NLS-1$
	}
		
	/**
	 * コンフィグレーションのコピー
	 * @param gsc GSCヘの接続情報
	 */	
	public void replicate(CommandParser cp, GSCdata gsc) {
		//Config名取得
		String srcCfgName = (String)cp.getConfigName().get(0);
		String destCfgName = (String)cp.getConfigName().get(1);

		// コピー元ConfigInfoオブジェクトの取得
		ConfigAction configAction = new ConfigAction(gsc);
		ConfigInfo configInfo = null;
		try {
			configInfo = configAction.get(srcCfgName);
		} catch (Exception e1) {
			// TODO 自動生成された catch ブロック
			System.out.println(MessagesCommandLine.getString("cui.error.config.copy", new Object[] {srcCfgName,destCfgName})); //$NON-NLS-1$
			e1.printStackTrace();
			return;
		}
		
		// コピー先ConfigInfoオブジェクトの設定
		configInfo.setConfigId(destCfgName);

		if(gsc == null)
			return;
		
		ConfigAction addConfig = new ConfigAction(gsc);
		try {
			if (addConfig.add(configInfo)){
				System.out.println(MessagesCommandLine.getString("cui.message.config.copy", new Object[] {srcCfgName,destCfgName})); //$NON-NLS-1$
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(MessagesCommandLine.getString("cui.error.config.copy", new Object[] {srcCfgName,destCfgName})); //$NON-NLS-1$
	}

	/**
	 * コンフィグレーションの表示
	 * @param gsc GSCヘの接続情報
	 */	
	public void show(GSCdata gsc) {
		ArrayList configList = null;
		//サーバ情報取得
		ConfigAction configAction = new ConfigAction(gsc);
		try {
			configList = configAction.getList();
		} catch (Exception e) {
			System.out.println(MessagesCommandLine.getString("cui.error.config.show")) ; //$NON-NLS-1$
			e.printStackTrace();
			return;
		}
		
		//Config情報表示
		System.out.println(MessagesCommandLine.getString("cui.message.config.show")) ; //$NON-NLS-1$
		Iterator it = configList.iterator();
		System.out.println(" CONFIG \t| DESCRIPTION \t| CACHE_REFRESH \t| RETRY_COUNT \t| DETECT_TIMEOUT \t| DISTRIBUTED_CONNECTION " + //$NON-NLS-1$
				"\t| PARTITION_MODE \t| SYNCRONIZE_MODE"); //$NON-NLS-1$
		System.out.println("----------------------------------------------"); //$NON-NLS-1$
		while (it.hasNext()) {
			ConfigInfo configInfo = (ConfigInfo)it.next();
			try {
				ConfigInfo configInfoDtl = configAction.get(configInfo.getConfigId());
				System.out.print(configInfoDtl.getConfigId() + "\t| "); //$NON-NLS-1$
				System.out.print(configInfoDtl.getDescription() + "\t| "); //$NON-NLS-1$
				System.out.print(configInfoDtl.getCacheReflesh() + "\t| "); //$NON-NLS-1$
				System.out.print(configInfoDtl.getRetryCount() + "\t| "); //$NON-NLS-1$
				System.out.print(configInfoDtl.getDefectTimeout() + "\t| "); //$NON-NLS-1$
				System.out.print(convertDist(configInfoDtl.getDistributedCon()) + "\t| "); //$NON-NLS-1$
				System.out.print(convertMode(configInfoDtl.isPertitionMode()) + "\t| "); //$NON-NLS-1$
				System.out.println(convertMode(configInfoDtl.isSyncMode()));
			} catch (Exception e) {
				// TODO 自動生成された catch ブロック
				System.out.println(MessagesCommandLine.getString("cui.error.config.show")) ; //$NON-NLS-1$
				e.printStackTrace();
				return;
			}	
		}

	}
	
	private String convertDist(int dist){
		String ret = "";
		if (dist == 0) {
			ret = MessagesCommandLine.getString("form.config.distribution.roundrobin");
		} else if (dist == 1) {
			ret = MessagesCommandLine.getString("form.config.distribution.fix");
		}
		return ret;
	}
	
	private String convertMode(boolean status){
		String ret = "";
		if (status) {
			ret = MessagesCommandLine.getString("yes");
		} else if (!status) {
			ret = MessagesCommandLine.getString("no");
		}
		return ret;
	}

}
