/*
 * $Id: discover.java,v 1.2 2005/08/18 00:02:44 rampil Exp $
 * Copyright (c) 2004 LOGICAL-PARADOX.ORG
 */
package org.logical_paradox.gdrn.shell.command;

import java.io.OutputStream;
import java.io.PrintWriter;

import org.logical_paradox.rss.Service;
import org.logical_paradox.rss.lookup.LookupFactory;
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;

/**
 * <pre>
 * ■discover
 * 
 * 【動作仕様】
 * 指定名称のサービスを検索します。
 * 検索の基点は現在選択されているDSRです。
 * --recursiveオプションを指定すると、現在のDSRに接続されているDSRに対して、
 * 再帰的に検索をします。このオプションの値は、再起検索の際の検索の深さを意味します。
 * 同オプションを指定しない場合、単に現在選択されているDSR内を検索して終了します。
 * 
 * 【書式】
 * discover [--recursive=<path count to trace recursively>] {--name=<service-name> | --type=<service-type>}
 * </pre>
 * 
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.2 $
 */
public class discover implements Command {
	public static final String USAGE = "discover [--recursive=<path count to trace recursively>] {--name=<service-name> | --type=<service-type>}";
	public String usage() {
		return USAGE;
	}
	public ResultCode execute(OutputStream o, ShellEnv env, Argument arg) throws CommandExecutionException, TerminationException {
		if(
			arg == null || arg.getArguments() == null || arg.getArguments().length != 0 ||
			arg.getOptions() == null || arg.getOptions().length == 0
		) {
			throw new CommandExecutionException("invalid command line. check statement.");
		}

		Option[] options = arg.getOptions();

		String serviceName = null;
		String serviceType = null;
		int recursiveDepth = 0;

		for(int i = 0; i < options.length; i++) {
			if("name".equals(options[i].getName())) {
				serviceName = options[i].getValue();
			} else if("type".equals(options[i].getName())) {
				serviceType = options[i].getValue();
			} else if("recursive".equals(options[i].getName())) {
				recursiveDepth = Integer.parseInt(options[i].getValue());
			} else {
				throw new CommandExecutionException("specified option '" + options[i].getName() + "' is invalid.");
			}
		}

		if(
			(serviceName != null && serviceType != null) ||
			(serviceName == null && serviceType == null)
		) {
			throw new CommandExecutionException("specify 'name' or 'type'.");
		}

		// サービスのルックアップ
		String dsruri = env.getProperty("DEFAULT_DSR_URI");
		PrintWriter pw = new PrintWriter(o);

		try {
			pw.println("searching..");
			Service service = null;
			if(serviceName != null) {
				service = LookupFactory.getLookup(dsruri).lookup(serviceName);
			} else {
				// サービスタイプの変換
				Integer type = (Integer)GdrnCommandConstant.services.get(serviceType);
				if(type == null) {
					throw new CommandExecutionException("specified command type is not defined.");
				}
				service = (Service)LookupFactory.getLookup(dsruri).lookup(type.intValue());
			}

			// 発見されたサービスのFQSNを表示する
			pw.println("service found named: [" + service.getFqsn() + "]");
			pw.println("done.");
		} catch (Exception e) {
			// コマンド実行例外
			e.printStackTrace();
			throw new CommandExecutionException("fatal problem found in progress.");
		} finally {
			pw.flush();
			pw.close();
		}

		return new ResultCode(ResultCode.STATUS_OK);
	}

}
