package JavaAgent.context;

import JavaAgent.agent.*;
import JavaAgent.resource.*;
import java.io.*;
import java.net.*;
import java.util.*;

/**
 * Subclass of AgentContext which uses the SocketInterface class for 
 * communication.<p>
 *
 * <hr>
 * Copyright (c) 1995, H. Robert Frost, Stanford University.
 * All rights reserved.<p>
 * Copyright (c) 1996, H. Robert Frost, Enterprise Integration Technologies,
 * Inc. All rights reserved.<p>
 *
 * RESTRICTED RIGHTS LEGEND: Use, duplication or disclosure by the 
 * Government is subject to restrictions as set forth in 
 * subparagraph(c)(1)(ii) of the Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 and in similar clauses in the
 * FAR and NASA FAR supplement.<p>
 * 
 * This software is bound by the terms and conditions listed in the
 * attached <a href="../LICENSE">LICENSE file</A>.
 * <hr>
 * @author <A HREF="http://cdr.stanford.edu/html/people/frost-bio.html"> Rob Frost</A>
 * @version 0.3 5/21/96 for Java(tm) Language Version 1.0.2
 */

public class SocketContext extends AgentContext {

  /**
   * Sets the parameters and creates the
   * CommInterface, represented Agent and possibly the AgentFrame.
   * @param params Runtime parameters for the AgentContext.
   */

  public SocketContext(SocketParams params){
    super(params);
  }

  /**
   * Creates an Agent object.
   * @return Success of creation.
   */  
  protected boolean addAgent(){
    if(params.init_url != null){
      A = new Agent(this, (params.name != null)?params.name:"Agent", 
		    params.init_url, params.shared_url, params.shared_dir, 
		    params.working_dir);
      A.init();
      return true;
    } else {
      addSystemMessage("Do not have location of initialization file!");
    }
    return false;
  }

  /**
   * Creates a SocketInterface for the Agent.
   */
  protected void createCommInterface(){
    comm = new SocketInterface(A, ((SocketParams)params).port);
    if( ((SocketInterface)comm).port >= 0){
      setAgentAddress(((SocketInterface)comm).port);
      comm_ready = true;
      SubmitAddress();
      A.setComm(comm);
    } else {
      addSystemMessage("Failed to create a Socket Interface for the Agent on "
		       + "port " + ((SocketParams)params).port + ", " +
		       "try a different port.");      
    }
  }

  /**
   * Sets the agents address, and name if no name was specified.
   */ 
  protected void setAgentAddress(int port){
    try{
      String host = null;
      InetAddress local_host = InetAddress.getLocalHost();
      String host_name = local_host.getHostName();
      /* Is the host_name just the computer ? */
      if(host_name.indexOf(".") < 0 ){
	/* use the IPaddress */
	String IPstr = local_host.toString();
	host = IPstr.substring(IPstr.indexOf("/")+1);
      } else {
	host = host_name;
      }
      if(params.name == null){ /* set the Agent name to the URL */
	A.setName(host_name +":" + port);
      }
      A.getResource("address").addElement(A.getName(),
		   new SocketAddress(host,port), true);    
    } catch (Exception e){
      addSystemMessage("Failed to set the Agent address.", e);
    }
  }
  
  /**
   * Send the agent's name and address to the ANS.
   */
  protected void SubmitAddress(){
    try{
      SocketAddress sa = (SocketAddress)(A.getResource("address")).getElement(A.getName(), RetrievalResource.BLOCK);
      String address_str = new String("(evaluate :sender " +
				      A.getName() +
				      " :receiver ANS :language KQML" +
				      " :ontology agent)");
      KQMLmessage address_msg = new KQMLmessage(address_str);
      address_msg.addFieldValuePair("content", "(tell-resource " +
				    ":type address :name " +
				    A.getName() + " :value " +
				    sa.getValue()+ ")");
      A.sendMessage(address_msg);
    }  catch (Exception e){
      addSystemMessage("Couldn't get local host.", e);
    }
  }


  /**
   * Called if the SocketContext is started as an application from the command
   * line. Command line args:<p><ul>
   * <li> -i init_file URL
   * <li> [-s] shared classes URL, for classes and other files which will
   * be shared with other agents.
   * <li> [-l] local directory for writing to the shared classes URL.
   * <li> [-w] working directory for saving local files, this should not
   * be included if the agent cannot access the local disk 
   * <li> [-n] name, only included if the Agent should automatically 
   * connect to the network.
   * <li> [-gui] create a GUI if this flag is included
   * <li> [-p] For for ServerSocket
   * </ul>
   * @param arg Array of command line arguments.
   */

  public static void main(String arg[]) {
    Hashtable args = AgentContext.parseArgs(arg);
    SocketContext sc = new SocketContext(new SocketParams(args));
  }

}



















