/*
 * Aleph Toolkit
 *
 * Copyright 1999, Brown University, Providence, RI.
 * 
 *                         All Rights Reserved
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose other than its incorporation into a
 * commercial product is hereby granted without fee, provided that the
 * above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Brown University not be used in
 * advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.
 * 
 * BROWN UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ANY
 * PARTICULAR PURPOSE.  IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE FOR
 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package aleph;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.Vector;
import java.io.File;

/**
 * System and user-specific customization.
 * <p>
 * Some of the more useful run-time flags:
 *<p>
 *<il>
 *<li> <code>-Daleph.batch</code>
 *<li> <code>-Daleph.java_g</code>
 *<li> <code>-Daleph.logging</code>
 *<li> <code>-Daleph.profile</code>
 *<li> <code>-Daleph.verbosity=</code><it>n</it>
 *<il>
 * @author Maurice Herlihy
 * @date   May 1999
 **/

public class Config {

  /**
   * Aleph version number.
   **/
  public static final String version = "1.1.0";

  /**
   * Unique port number for servers.
   **/
  public static final int PORT = 0; // must be between 1024 and 65535,

  /**
   * Array of default host names.
   **/
  public static String[] hosts; // initialized below

  /**
   * Make your current host first in the hosts array.  Useful if you don't
   * always use the same workstation.
   **/
  static boolean localHostFirst = false;

  /**
   * Initial verbosity level, between 0 and <it>max(7,verbosity)</it>.
   * 0 is laconic, 1 tags output lines, 2 prints statistics, etc.
   * Override with <code>-Daleph.verbosity=<it>n</it></code>.
   **/
  public static final int verbosity = 0;

  /**
   * If zero, Aleph initially creates one PE at each active host.  If <i>n</i>,
   * Aleph initially creates <i>n</i> PEs, in round-robin order at the hosts.
   * Overridden with <code>-Daleph.numPEs=<it>n</it></code>, or by the console.
   **/
  public static final int numPEs = 0; // One per host.

  /**
   * Maximum number of PEs.
   * Override with <code>-Daleph.maxPEs=<it>n</it></code>.
   **/
  public static final int maxPEs = 32;

  /**
   * Where to find java.
   **/
  public static String pathJava;

  /**
   * Where to find java_g.
   **/
  public static String pathJava_g;

  /**
   * Use <code>java_g</code>?  Also set by <code>-Daleph.java_g</code> flag.
   **/
  public static final boolean java_g = false;

  /**
   * Turn on profiling?  Also set by <code>-Daleph.profile</code> flag.
   **/
  public static final boolean profile = false;

  /**
   * Log the console?  Also set by <code>-Daleph.logging</code> flag.
   **/
  public static final boolean logging = false;

  /**
   * The Aleph server writes logs, debugging output, and instrumentation output
   * to this directory.  If the directory does not exist, it will try to create
   * it.  The directory name can be absolute or relative.
   **/
  public static File logDir;
  static {                      // static initializer for logDir
    File dir = new File("logs");
    if (! dir.exists()) {       // create the directory
      boolean ok = dir.mkdir();
      if (!ok)                // create failed, use current directory
        dir = new File("");
      System.err.println("Warning: using log directory " +
                         dir.getAbsolutePath());
    }
    logDir = dir;
  }
  
  /**
   * Run without an AWT console if <i>true</i>.
   * Also controlled by run-time flag <code>-Daleph.batch</code>.
   **/
  public static final boolean batch = false; // default off

  /**
   * Where to find rsh (used by Unix tools.)
   * Override with <code>-Daleph.pathRsh=<it>p</it></code>.
   **/
  public static final String pathRsh = "/usr/bin/rsh"; // default

  /**
   * Define non-standard JIT compilers.  Built-in values include ``default'',
   * and ``none'' which means use the interpreter.  These compilers must be
   * defined at every PE.
   **/
  //public static final String[] compilers = {"aaa", "bbb"};
  public static final String[] compilers = null;

  /**
   * Banner displayed on startup.
   **/
  public static final String banner = "Aleph Toolkit v 0.93 (Winter 1999) Copyright (c) 1998 Brown University";


  /**
   * What to display in <i>about</i> menu item.
   **/
  public static String[] about = {Config.banner,
				  "http:www.cs.brown.edu/~mph/aleph",
				  "aleph@cs.brown.edu"
  };

  /**
   * Number of worker threads to handle asynchronous messages.
   * Should do something more intelligent at run-time.
   **/
  public static int numWorkers = 8;

  /**
   * Background color for output windows.
   **/
   public static java.awt.Color background = new java.awt.Color(65, 105, 225); // RoyalBlue4

  /**
   * Foreground color for output windows.
   **/
  public static java.awt.Color foreground = java.awt.Color.white;

  /**
   * Default contents of command line.
   **/
  public static final String defaultCommand = "aleph.examples.Hello";

  /**
   * This array defines the locally-supported Communication Manager classes.
   * The even entries are class names, and the odd entries are short
   * informative labels to display on the console.
   * <br>
   * The first entry the default, unless overridden by
   * <code>-Daleph.communicationManager=LABEL</code>.
   **/
  public static String[] communicationManagers = {
    "aleph.comm.rmi.CommunicationManager", "RMI",
    "aleph.comm.udp.CommunicationManager", "UDP",
    "aleph.comm.tcp.CommunicationManager", "TCP"
  };

  /**
   * This array defines the locally-supported Directory Manager classes.
   * The even entries are class names, and the odd entries are short
   * informative labels to display on the console.
   * <br>
   * The first entry the default, unless overridden by
   * <code>-Daleph.directoryManager=LABEL</code>.
   **/
  public static String[] directoryManagers = {
    "aleph.dir.home.HomeDirectory",     "Home",
    "aleph.dir.arrow.ArrowDirectory",   "Arrow",
    "aleph.dir.arrow1.ArrowDirectory",  "Arrow1",
    "aleph.dir.arrow2.ArrowDirectory",  "Arrow2",
    "aleph.dir.hybrid.HybridDirectory", "Hybrid",
  };
  
  /**
   * This array defines the locally-supported Event Manager classes.
   * The even entries are class names, and the odd entries are short
   * informative labels to display on the console.
   * <br>
   * The first entry the default, unless overridden by
   * <code>-Daleph.eventManager=LABEL</code>.
   **/
  public static String[] eventManagers = {
    "aleph.event.SimpleEventManager",   "Simple"
  };

  /**
   * This array defines the locally-supported Transaction Manager classes.
   * The even entries are class names, and the odd entries are short
   * informative labels to display on the console.
   * <br>
   * The first entry the default, unless overridden by
   * <code>-Daleph.transactionManager=LABEL</code>.
   **/
  public static String[] transactionManagers = {
    "aleph.trans.SimpleTransactionManager",   "Simple"
  };

  // Personal customization
  static {
    String[] brownHosts = {"elmgrove", "botrytis", "markov", "barney",
                           "pebbles", "bruford", "reverb", "hamlet", "gromit"};
    //String[] crlHosts = {"banjo", "clove", "indian", "reef"};
    String[] crlHosts = {"banjo", "clove", "spa", "reef", "hawk", "gil", "cutter", "clipper", "sloop", "indian", "square"};
    String[] laptopHosts   = {"mphhost"};
    //    String[] ntHosts       = {"mphhome", "banjo.crl.dec.com", "clove.crl.dec.com", "spa.crl.dec.com", "reef.crl.dec.com", "hawk.crl.dec.com",};
    String[] ntHosts       = {"mphhome.edu"};
    String[] brandeisHosts = {"cyclops", "lachesis", "atropos"};

    String osName = System.getProperty("os.name");

    if (osName.equalsIgnoreCase("Solaris") ||
        osName.equalsIgnoreCase("SunOS")) {
      hosts = brownHosts;
      pathJava = "/pro/java/jdk1.2/bin/java";
      pathJava_g = "/pro/java/jdk1.2/bin/java";
    } else if (osName.equalsIgnoreCase("Digital UNIX")) { // DU inconsistent case
      hosts = crlHosts;
      pathJava = "/usr/bin/java";
      pathJava_g = "/usr/bin/java_g";
    } else if (osName.equalsIgnoreCase("Windows 95")) {
      hosts = laptopHosts;
      pathJava = "c:/jdk1.1.6/bin/java";
      pathJava_g = "c:/jdk1.1.6/bin/java_g";
    } else if (osName.equalsIgnoreCase("Windows NT")) {
      hosts = ntHosts;
      pathJava = "c:/jdk1.1.7/bin/java";
      pathJava_g = "c:/jdk1.1.7/bin/java_g";
    } else if (osName.equalsIgnoreCase("linux")) {
      hosts = brandeisHosts;
      pathJava = "/usr/local/java/bin/java";
      pathJava_g = "/usr/local/java/bin/java_g";
    } else {
      System.err.println("Unrecognized os " + osName);
      System.exit(-1);
    }
  }

}
