/*
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2005 satoshi akabane(akabane@logical-paradox.org)
 * $Id: format.java,v 1.2 2005/09/07 13:38:06 rampil Exp $
 */
package org.logical_paradox.vsan.tools.console.command;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import org.logical_paradox.common.util.StringUtils;
import org.logical_paradox.shell.Argument;
import org.logical_paradox.shell.Command;
import org.logical_paradox.shell.Option;
import org.logical_paradox.shell.ResultCode;
import org.logical_paradox.shell.ShellEnv;
import org.logical_paradox.shell.exception.CommandExecutionException;
import org.logical_paradox.shell.exception.TerminationException;
import org.logical_paradox.vsan.dac.Response;
import org.logical_paradox.vsan.dac.ResponseCode;
import org.logical_paradox.vsan.dac.command.Protocol;
import org.logical_paradox.vsan.tools.console.DacConsoleConstant;
import org.logical_paradox.vsan.tools.console.util.SocketWriter;


/**
 * <pre>
 * ■format
 * 
 * 【動作仕様】
 * DACに対してシャットダウンを要求します。
 * このコマンドは、dacコマンドによって設定された'dac'環境変数を参照します。
 * 
 * 【書式】
 * format --domain-name=<domain-name> --begin=<begin-record-no> --end=<end-record-no> --record-size=<record-size> [hostname[:<port>]]
 * 
 * </pre>
 * 
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.2 $
 */
public class format implements Command {
	public static final String USAGE = "format --domain-name=<domain-name> --record-size=<record-size> [hostname[:<port>]]";

	public String usage() {
		return USAGE;
	}

	public ResultCode execute(OutputStream o, ShellEnv env, Argument a) throws CommandExecutionException, TerminationException {
		// ドメインデータベースのフォーマット要求を送信する
		if(a == null || a.getOptions().length != 2) {
			throw new CommandExecutionException();
		}
		String domain = null;
		int recordSize = -1;

		// オプションの解析
		Option[] options = a.getOptions();
		for(int i = 0; i < options.length; i++) {
			Option opt = options[i];
			if("domain-name".equals(opt.getName())) {
				domain = opt.getValue();
			} else if("record-size".equals(opt.getName())) {
				recordSize = Integer.parseInt(opt.getValue());
			}
		}

		if(StringUtils.isEmpty(domain) == true || recordSize < 0) {
			throw new CommandExecutionException();
		}

		// 接続先DACの決定
		String dac = null;

		if(a == null || a.getArguments().length == 0) {
			dac = env.getProperty(DacConsoleConstant.ENV_DAC);
		} else if(a.getArguments().length > 1) {
			throw new CommandExecutionException();
		} else {
			dac = a.getArguments()[0];
		}

		try {
			PrintWriter pw = new PrintWriter(o);
			pw.println("formatting a domain database...");

			ByteBuffer buffer = ByteBuffer.allocate(1 + 32 + 4).order(ByteOrder.BIG_ENDIAN);
			buffer.put((byte)Protocol.P_FORMAT);		
			buffer.put((domain + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0").substring(0, 32).getBytes());
			buffer.putInt(recordSize);
			buffer.rewind();

			Response response = SocketWriter.send(dac, buffer.array(), true);

			if(response.getResponseCode() == ResponseCode.OK) {
				pw.println("done. check status with 'status' command.");
			} else {
				pw.println("command execution exception");
			}
			pw.flush();
			pw.close();
		} catch(IOException e) {
			throw new CommandExecutionException(e.getMessage());
		}
		return new ResultCode(ResultCode.STATUS_OK);
	}

}
