package org.postgresforest.tool.cli.action;

import java.util.ArrayList;

import org.postgresforest.tool.Logger;
import org.postgresforest.tool.lib.Config;
import org.postgresforest.tool.lib.ForestToolException;
import org.postgresforest.tool.lib.GSCdata;
import org.postgresforest.tool.util.CommandParser;
import org.postgresforest.tool.util.MessagesCommandLine;
import org.postgresforest.tool.util.Table2StringUtil;

/**
 * コンフィグレーションへのコマンドラインツール用のアクションを提供するクラス
 */
public class ConfigActions {
	private static final String[] SHOW_CONFIG_HEADER = {"CONFIG","DESCRIPTION","CACHE_REFRESH","RETRY_COUNT","DETECT_TIMEOUT","DISTRIBUTED_CONNECTION ","NON-PARTITION_MODE","SYNCRONIZE_MODE" }; //$NON-NLS-1$

	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$

	/**
	 * コンフィグレーションの作成
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 */	
	public static void create(CommandParser cp, GSCdata gsc) {

		
		//Config名取得
		String cfgName = cp.getConfigName();
		if(cfgName == null || cfgName.equals("")){
			//引数が不正
			// FIXME:
			Logger.error("invalid argument");
			return;
		}
		
		//コンフィギュレーション作成
		Config config = gsc.createConfig(cfgName);
		if(config == null){
			Logger.error(MessagesCommandLine.getString("cui.error.config.create", new Object[] {cfgName}));
			return;
		}

		Logger.println(MessagesCommandLine.getString("cui.message.config.create", new Object[] {cfgName}));
	}
	
	/**
	 * コンフィグレーションの削除
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 */	
	public static void drop(CommandParser cp, GSCdata gsc) {
		String id = cp.getConfigName();
		if(id == null || id.equals("")){
			//引数が不正
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}

		if(id.equals(Config.DEFAULT_CONFIG_NAME)){
		    
		    Logger.error(MessagesCommandLine.getString("errors.gsc.config.del.default"));
		    return;
		}

		//削除
		if( ! gsc.dropConfig(id) ){
			Logger.error(MessagesCommandLine.getString("cui.error.config.drop", new Object[] {id}));
		}

		//成功
		Logger.println(MessagesCommandLine.getString("cui.message.config.drop", new Object[] {id}));
	}

	/**
	 * コンフィグレーションの項目設定
	 * @param gsc GSCヘの接続情報
	 */	
	public static void set(CommandParser cp, GSCdata gsc) {

		// Config名の取得
		String id = cp.getConfigName();
		if(id == null || id.equals("")){
			//引数が不正
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}
		
		
		Config config = gsc.getConfig(id);
		if(config == null){
			//該当するコンフィグ情報が無い
			Logger.error(MessagesCommandLine.getString("cui.error.config.set", new Object[] {id}));
			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.equalsIgnoreCase(CFGNAME_OPTION_NAME) ) {
				String cfgName = (String)paramValues.get(i);
				config.setId(cfgName);
			} else if (paramName.equalsIgnoreCase(DESCRIPTION_OPTION_NAME) ) {
				String descript = (String)paramValues.get(i);
				config.setDescription(descript);
			} else if (paramName.equalsIgnoreCase(REFRESH_OPTION_NAME) ) {
				int refresh = Integer.parseInt((String)paramValues.get(i));
				config.setCacheRefresh(refresh);
			} else if (paramName.equalsIgnoreCase(RETRYCOUNT_OPTION_NAME) ) {
				int retry = Integer.parseInt((String)paramValues.get(i));
				config.setRetryCount(retry);
			} else if (paramName.equalsIgnoreCase(DETECTTIMEOUT_OPTION_NAME) ) {
				int timeout = Integer.parseInt((String)paramValues.get(i));
				config.setDefectTimeout(timeout);
			} else if (paramName.equalsIgnoreCase(DISTRIBUTION_OPTION_NAME) ) {
				int dist = Integer.parseInt((String)paramValues.get(i));
				config.setDistributedConnection(dist);
			} else if (paramName.equalsIgnoreCase(PARTMODE_OPTION_NAME) ) {
				String pmode = (String)paramValues.get(i);
				config.setPartitionMode( Integer.parseInt(pmode) );
			} else if (paramName.equalsIgnoreCase(SYNCMODE_OPTION_NAME) ) {
				String smode = (String)paramValues.get(i);
				config.setSynchronizeMode( Integer.parseInt(smode) );
			} else {
				Logger.error(MessagesCommandLine.getString("cui.error.commandparser.param.invalid"));
				return;
			}
		}

		Logger.println(MessagesCommandLine.getString("cui.message.config.set", new Object[] {id}));
	}
		
	/**
	 * コンフィグレーションのコピー
	 * @param gsc GSCヘの接続情報
	 */	
	public static void replicate(CommandParser cp, GSCdata gsc) {
		//Config名取得
		String srcCfgName = cp.getConfigName();
		if(srcCfgName == null || srcCfgName.equals("")){
			//引数が不正
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}
		String destCfgName = (String)cp.getConfigCopyName();
		if(destCfgName == null || destCfgName.equals("")){
			//引数が不正
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}

		//
		Config config = gsc.createConfig(destCfgName,srcCfgName);
		if(config == null){
			//コンフィグ情報コピー失敗
			Logger.error(MessagesCommandLine.getString("cui.error.config.copy",
													   new Object[] {srcCfgName,destCfgName}));
			return;
		}

	Logger.println(MessagesCommandLine.getString("cui.message.config.copy", new Object[] {srcCfgName,destCfgName}));
	}

	/**
	 * コンフィグレーションの表示
	 * @param gsc GSCヘの接続情報
	 */	
	public static void show(GSCdata gsc) {

		
		String[] configNames;

		//コンフィグレーション名のリストを取得
		try {
			configNames = gsc.getConfigNames();
			
		} catch (ForestToolException e) {
			Logger.error(MessagesCommandLine.getString("cui.error.config.show")) ;
			Logger.error(e.getMessage());
			Logger.trace(e);
			return;
		}

		
		//Config情報表示
		Logger.println(MessagesCommandLine.getString("cui.message.config.show")) ;

		Table2StringUtil table2StringUtil = new Table2StringUtil( SHOW_CONFIG_HEADER );
		

		for (int i = 0; i < configNames.length; i++) {
			Config config = gsc.getConfig(configNames[i]);
			if(config == null){
				//インスタンス情報の取得失敗
				Logger.error(MessagesCommandLine.getString("cui.error.config.show"));
				return;
			}


			ArrayList row = new ArrayList();
			row.add(config.getId());
			row.add(config.getDescription());
			row.add(new Integer(config.getCacheRefresh()));
			row.add(new Integer(config.getRetryCount()));
			row.add(new Integer(config.getDefectTimeout()));

			int distMode = config.getDistributedConnection();
			if ( distMode == Config.CONN_RR ) {
				row.add(MessagesCommandLine.getString("form.config.distribution.roundrobin"));
			} else if (distMode == Config.CONN_FIXED ) {
				row.add(MessagesCommandLine.getString("form.config.distribution.fix"));
			}else{
				// FIXME:
				row.add("UNKNOWN VALUE");
			}
			
			int nonPartMode = config.getPartitionMode();
			if (nonPartMode == Config.PARTMODE_NOPART) {
				row.add(MessagesCommandLine.getString("yes"));
			} else if (nonPartMode == Config.PARTMODE_PART) {
				row.add(MessagesCommandLine.getString("no"));
			}else{
				// FIXME:
				row.add("UNKNOWN VALUE");
			}

			int syncMode = config.getSynchronizeMode();
			if (syncMode == Config.SYNCMODE_SYNC) {
				// FIXME:
				row.add("Sync");
			} else if (syncMode == Config.SYNCMODE_NOSYNC) {
				// FIXME:
				row.add("UnSync");
			}else{
				// FIXME:
				row.add("UNKNOWN VALUE");
			}

			table2StringUtil.addRow(row);
		}
		

		table2StringUtil.print();

	}
	
	

}
