package org.postgresforest.tool.cli;

import org.postgresforest.tool.Logger;
import org.postgresforest.tool.cli.action.DbActions;
import org.postgresforest.tool.cli.action.TableActions;
import org.postgresforest.tool.lib.Database;
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.Parser;
import org.postgresforest.tool.util.ReWriter;

/**
 * コマンドラインクラス コマンドの受けつけ、割り振りを行う。
 */
public class DbCommandProcessor extends AbstractCommandProcessor {

	private AbstractCommandProcessor m_gscCommandProcessor = null;
	private Database m_db = null;

	public DbCommandProcessor(GSCdata gsc, AbstractCommandProcessor gscProcesser, String dbname) throws ForestToolException{
		super(gsc);
		m_gscCommandProcessor = gscProcesser;
		
		m_db = m_gsc.getDatabase(dbname);
		
	}


	public void printPrompt() {
		System.out.println("");
		System.out.print("[" + m_db.getDatabaseName() + "]> ");
		System.out.flush();

	}

	protected AbstractCommandProcessor executeCommand(CommandParser cp, String command) {

		//環境構築コマンドタイプの取得
		int cpType = cp.getType();

		switch (cpType) {
		
		case CommandParser.CLOSE_DB:
			Logger.println(MessagesCommandLine.getString("cui.message.db.close",
														 new Object[] { m_db.getDatabaseName() }));
			//戻り値にGsc処理クラスを設定
			return m_gscCommandProcessor;

		case CommandParser.SHOW_TABLE:
			TableActions.showTable(m_db);
			break;

		case CommandParser.SHOW_TABLE_COLUMN:
			TableActions.showTableColumn(cp, m_db);
			break;

		case CommandParser.PART_TABLE:
			TableActions.part(cp, m_db);
			break;

		case CommandParser.PART_TABLE2:
			TableActions.part2(cp, m_db);
			break;

		case CommandParser.UNPART_TABLE:
			TableActions.unpart(cp, m_db);
			break;

		case CommandParser.SET_PRIORITY:
			TableActions.setPriority(cp, m_db );
			break;

		case CommandParser.SHOW_PRIORITY:
			TableActions.showPriority(cp, m_db );
			break;

		case CommandParser.OPEN_DB:
			// DBが既にOpen状態の場合
			Logger.error(MessagesCommandLine.getString("cui.error.db.dupricateopen",
													   new Object[] { m_db.getDatabaseName() }));
			break;

		
		default:
			// DDLコマンドタイプの取得
			Parser pr = null;
			try {
				command = ReWriter.toLowerSql(command);
				pr = new Parser(command);
			} catch (Exception e) {
				Logger.error(MessagesCommandLine.getString("cui.error.parser"));
				Logger.error(e.getMessage());
				Logger.trace(e);
				break;
			}
			int prType = pr.getType();
			if (prType == Parser.DML) {
				// DML実行(Jpsqlの呼出し)
				// To do
				Logger.error(MessagesCommandLine.getString("cui.error.dml.notsupport"));
			} else if (prType != Parser.NONE) {
				// DDL実行
				DbActions.executeDdl( command, pr, m_db);
			}else{
				// 未対応のコマンド
				Logger.error(MessagesCommandLine.getString("cui.error.command.noexist"));
			}

			
			break;
		}
		
		return this;

	}



	protected void processSlashCommandTable(String line) {
		if (line.startsWith("\\ft ")) { //$NON-NLS-1$
			// テーブル名の取得
			String table = CommandParser.extractSlashCmdArgument(line, 4);
			if (!table.equals("")) { //$NON-NLS-1$
				// テーブル情報の表示
				 TableActions.showTableColumn(table, m_db);
				return;
			}
		}
		 TableActions.showTable( m_db);

	}

	protected void processSlashCommandPriority(String line) {
		if (line.startsWith("\\fp ")) { //$NON-NLS-1$
			// テーブル名の取得
			String table = CommandParser.extractSlashCmdArgument(line, 4);
			if (!table.equals("")) { //$NON-NLS-1$
				// 優先度の表示
				 TableActions.showPriority(table, m_db);
				return;
			}
		}
		Logger.error(MessagesCommandLine.getString("cui.error.help.back.fp"));
		Logger.println(MessagesCommandLine.getString("cui.help.back.f"));

	}


}
