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;

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

	static private String[] SHOW_GSC_HEADER = {"DBNAME", "HOST", "PORT", "SERVERID"}; 
	
	/**
	 * GSCの新規作成
	 * @param loginInfo ログイン情報
	 */
	static public void make(String hostname, String portno, String gscname, String username,	String userpass ) {
		
		try {
			GSCdata.initialize(hostname, portno, gscname, username, userpass );
			Logger.println(MessagesCommandLine.getString("cui.message.gsc.make", new Object[] {gscname}));
		} catch (ForestToolException e) {
			// FIXME: 
			Logger.error(MessagesCommandLine.getString("cui.error.gsc.make", new Object[] {gscname}));
		    Logger.error(e.getMessage());
			Logger.trace(e);
		}
	}

	/**
	 * GSCの追加作成
	 * GSC名は接続先のものと同一なので、GSCのコピーを行う
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 */
	public static void create(CommandParser cp, GSCdata gsc) {

		//コマンドラインからIDを取得
		int id = -1;
		try {
			id = Integer.parseInt((String)cp.getServer().get(0));
		} catch (NumberFormatException e) {
			//引数が不正
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}

		//コマンドラインから強制フラグを取得
		boolean force = cp.isForce();

		//IDからインスタンス情報取得
		Instance instance = gsc.getInstance(id);
		if ( instance==null )
		{
			Logger.error("Cannot get instance[" + id + "].");
			return;
		}
		String gscName = gsc.getGscName();
		int serverid = instance.getId();

		if(instance == null){
			//対象のインスタンス情報が登録されていません
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}
		
		//GSCコピー実行
		if( ! gsc.copy(instance,force) ){
			Logger.error(MessagesCommandLine.getString("cui.error.gsc.create",
													   new Object[] {gscName, new Integer(serverid)}) );
			return;
		}

		Logger.println(MessagesCommandLine.getString("cui.message.gsc.create",
													 new Object[] {gscName, new Integer(serverid)})) ;

		
	}
	
	/**
	 * GSCの削除
	 * @param cp コマンド解析結果
	 * @param gsc GSCヘの接続情報
	 */
	public static void drop(CommandParser cp, GSCdata gsc) {
		//最後のGSCの削除の場合、確認メッセージを表示する
/*		if(view.isLastGsc()){
			Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
			if(!MessageDialog.openQuestion(shell, 
					Messages.getString("button.delete"), 
					Messages.getString("message.delgsc.confirm"))){
				return ;
			}
		}*/
		
		
		//コマンドラインからIDを取得
		int id = 0;
		try {
			id = Integer.parseInt((String)cp.getServer().get(0));
		} catch (NumberFormatException e) {
			//引数が不正
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}

		//IDからインスタンス情報取得
		Instance instance = gsc.getInstance(id);
		if(instance == null){
			//対象のインスタンス情報が登録されていません
			// FIXME:
			Logger.error("invalid argument.");
			return;
		}
		
		//GSC削除
		if( ! gsc.drop(instance) ){
			//削除に失敗しました。
			Logger.error(MessagesCommandLine.getString("cui.error.gsc.drop",
													   new Object[] {gsc.getGscName(), new Integer(instance.getId())}) );
			return;
		}
		
		//削除しました
		Logger.println(MessagesCommandLine.getString("cui.message.gsc.drop",
													 new Object[] {gsc.getGscName(), new Integer(instance.getId())}) );
		
	}
	
	/**
	 * GSCの整合性チェック
	 * @param gsc GSCヘの接続情報
	 */
	public static void check(GSCdata gsc) {
		//グローバルシステムカタログ整合性チェック処理

		String gscNmae = gsc.getGscName();
		//GSCの同一性をチェック
		
		int[] ids = gsc.getGscInstances();
		for (int i=0 ; i<ids.length ; i++)
		{
			Instance ins =  gsc.getInstance(ids[i]);

			if ( !gsc.equals(ins) )
				Logger.warning("GSC consistency was broken on " + ins.toString());
		}

		if ( !gsc.validate(GSCdata.VALIDATE_SCHEMA|GSCdata.VALIDATE_RECORD_COUNT) )
		{
			Logger.error(MessagesCommandLine.getString("cui.error.gsc.check") );
		}

		/*
		int[] ids;

		//インスタンスIDのリストを取得
		try {
			ids = gsc.getInstanceIds();
			
		} catch (ForestToolException e) {
			Logger.error(MessagesCommandLine.getString("cui.error.gsc.check") );
			Logger.error(e.getMessage());
			Logger.trace(e);
			return;
		}
		

		//IDからインスタンス情報取得し表示
		
		for (int i = 0; i < ids.length; i++) {
			int id = ids[i];
			//IDからインスタンス情報取得
			Instance instance = gsc.getInstance(id);
			if(instance == null){
				//インスタンス情報の取得失敗
				Logger.error(MessagesCommandLine.getString("cui.error.gsc.check") );
				return;
			}
			
			//インスタンス情報からGSC名を取得
			String[] gscNames = instance.getGscNames();
			if(gscNames != null){
				for (int j = 0; j < gscNames.length; j++) {
					//該当のGSCを含んでいたら、
					if( gscNmae.equals(gscNames[j]) ) {
						//GSCの同一性チェック
						if( ! gsc.equals(instance) ){
							//FIXME:
							//エラーが起こっても、チェックは継続？？？
							Logger.error(MessagesCommandLine.getString("cui.error.gsc.check") );
							return;
						}
						
						break;
					}
				}
				
			}else{
				//@@エラー？
				//FIXME
				Logger.error(MessagesCommandLine.getString("cui.error.gsc.check") );
				return;
			}
		}
		
	
		
		
		//GSCの内容とデータベースのスキーマ、各テーブルのレコード数をチェック
		if ( ! gsc.validate(GSCdata.VALIDATE_SCHEMA | GSCdata.VALIDATE_RECORD_COUNT)) {
			Logger.error(MessagesCommandLine.getString("cui.error.gsc.check") );
			return;
		}
		*/

		Logger.println(MessagesCommandLine.getString("cui.message.gsc.check")) ;
	}
	
	/**
	 * GSCの表示
	 * @param gsc GSCヘの接続情報
	 */
	public static void show(GSCdata gsc) {

		int[] ids = gsc.getGscInstances();

		if ( ids==null )
		{
			Logger.error(MessagesCommandLine.getString("cui.error.gsc.show"));
			return;
		}
		
		//GSC情報表示
		Logger.println(MessagesCommandLine.getString("cui.message.gsc.show"));

		Table2StringUtil table2StringUtil = new Table2StringUtil( SHOW_GSC_HEADER );

		//IDからインスタンス情報取得し表示
		
		for (int i = 0; i < ids.length; i++) {
			int id = ids[i];
			//IDからインスタンス情報取得
			Instance instance = gsc.getInstance(id);
			if(instance == null){
				//インスタンス情報の取得失敗
				Logger.error(MessagesCommandLine.getString("cui.error.gsc.show"));
				return;
			}

			//インスタンス情報を表示
			ArrayList row = new ArrayList();
			row.add(gsc.getGscName());
			row.add(instance.getHostName());
			row.add(instance.getPortNumber());
			row.add(new Integer(instance.getId()));
			table2StringUtil.addRow(row);
		}
		
		table2StringUtil.print();
	}
}
