package org.postgresforest.tool.cli.action;


import java.util.ArrayList;

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

/**
 * インスタンスへのコマンドラインツール用のアクションを提供するクラス
 */
public class InstanceActions {

	static private final String[] SHOW_INSTANCE_HEADER = {"SERVERID", "HOST", "PORT", "STATUS"}; 
	static public final int SERVER_RUNNING = 1; 
	static public final int SERVER_TROUBLE = -1; 

	/**
	 * インスタンスの作成
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 */
	public static void create(CommandParser cp, GSCdata gsc) {

		//ホスト名、ポートNoを取得
		String host = cp.getHost();	
		if(host == null || host.equals("")){
			//引数が不正
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}		
		String port = cp.getPort();	
		if(port == null || port.equals("")){
			//引数が不正
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}		
		
		//インスタンス登録
		Instance instance = gsc.registerInstance(host, port);
		if(instance == null){
			Logger.error(MessagesCommandLine.getString("cui.error.instance.create", new Object[] { host, port}) );
			return;
		}
		//インスタンス情報にステータスを設定
		if(! instance.setStatus(SERVER_RUNNING)){
			Logger.error(MessagesCommandLine.getString("cui.error.instance.set.up",
													   new Object[]{Integer.toString(instance.getId())}));
			return;
		}
		Logger.println(MessagesCommandLine.getString("cui.message.instance.create", new Object[]{host, port}));
	}
	
	/**
	 * インスタンスの削除
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 */	
	public static void drop(CommandParser cp, GSCdata gsc) {
		String id = (String)cp.getServer().get(0);
		
		//インスタンス削除
		if(id != ""){ //$NON-NLS-1$
			//インスタンス削除実行
			if (gsc.unregisterInstance(Integer.parseInt(id))){
				Logger.println(MessagesCommandLine.getString("cui.message.instance.drop", new Object[] {id}));
				return;
			}
		}	
		Logger.error(MessagesCommandLine.getString("cui.error.instance.drop", new Object[] {id}));
	}
	
	/**
	 * インスタンスの表示
	 * @param gsc GSCヘの接続情報
	 */		
	public static void show(GSCdata gsc) {
		int[] ids;

		//インスタンスIDのリストを取得
		try {
			ids = gsc.getInstanceIds();
			
		} catch (ForestToolException e) {
			Logger.error(MessagesCommandLine.getString("cui.error.instance.show")) ;
			Logger.error(e.getMessage());
			Logger.trace(e);
			return;
		}
		
		
		//IDからインスタンス情報取得し表示
		System.out.println(MessagesCommandLine.getString("cui.message.instance.show")) ; //$NON-NLS-1$

		Table2StringUtil table2StringUtil = new Table2StringUtil( SHOW_INSTANCE_HEADER );

		if(ids != null ){

			for (int i = 0; i < ids.length; i++) {
				int id = ids[i];
				Instance instance = gsc.getInstance(id);
				if(instance == null){
					//インスタンス情報の取得失敗
					Logger.error(MessagesCommandLine.getString("cui.error.instance.show"));
					return;
				}
				ArrayList row = new ArrayList();
	
				row.add(new Integer(instance.getId())); //$NON-NLS-1$
				row.add(instance.getHostName()); //$NON-NLS-1$
				row.add(instance.getPortNumber()); //$NON-NLS-1$
				row.add(convertStatus(instance.getStatus())); //$NON-NLS-1$
				table2StringUtil.addRow(row);
				
			}
		}
		
		table2StringUtil.print();

	}

	/**
	 * インスタンスの状態設定
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 * @param status インスタンスの設定状態
	 * 	 */	
	public static void set(CommandParser cp, GSCdata gsc, int status) {	


		//コマンドラインからIDを取得
		int id = Integer.parseInt((String)cp.getServer().get(0));

		//IDからインスタンス情報取得
		Instance instance = gsc.getInstance(id);
		if(instance == null){
			Logger.error(MessagesCommandLine.getString("cui.error.instance.set",
													   new Object[]{Integer.toString(id)}));
			return;
		}
		
		//インスタンス情報にステータスを設定
		if(! instance.setStatus(status)){
			Logger.error(MessagesCommandLine.getString("cui.error.instance.set.up",
													   new Object[]{Integer.toString(id)}));
			return;
		}
		
		//終了メッセージ表示
		if (status == SERVER_RUNNING) {
			Logger.println(MessagesCommandLine.getString("cui.message.instance.set.up",
														 new Object[]{Integer.toString(id)}));
		} else if (status == SERVER_TROUBLE) {
			Logger.println(MessagesCommandLine.getString("cui.message.instance.set.down",
														 new Object[]{Integer.toString(id)}));
		}
		
	}
	
	private static String convertStatus(int status) {
		String ret = "";
		if (status == SERVER_RUNNING) {
			ret = MessagesCommandLine.getString("form.running");
		} else if (status == SERVER_TROUBLE) {
			ret = MessagesCommandLine.getString("form.stopping");			
		}else{
			//FIXME:
			ret = "unknown status";
		}
		return ret;
	}
}
