// joi/7/juno/Juno.java                         
//                                                            
//                                                            
//  Copyright 2003 Bill Campbell and Ethan Bolker                         
                                                            
import java.io.*;
import java.util.*;
import java.lang.*;

/** 
 * Juno (Juno's Unix NOt) mimics a command line operating system 
 * like Unix.  
 * <p>
 * A Juno system has a name, a set of Users, a JFile system,
 * a login process and a set of shell commands.
 * 
 * @see User
 * @see JFile
 * @see ShellCommand
 *
 * @version 7
 */

public class Juno 
{
    private final static String os      = "Juno";
    private final static String version = "7";

    private String    hostName;   // host machine name
    private Map       users;      // lookup table for Users
    private Terminal  console;    // for input and output

    private Directory slash;      // root of JFile system
    private Directory userHomes;  // for home directories

    private ShellCommandTable commandTable; // shell commands

    /**
     * Construct a Juno (operating system) object.
     *
     * @param hostName  the name of the host on which it's running.
     * @param echoInput should all input be echoed as output?
     */

    public Juno( String hostName, boolean echoInput )
    {
        // initialize the Juno environment ...

        this.hostName = hostName;
        console       = new Terminal( echoInput );
        users         = new TreeMap();           // for registered Users
        commandTable  = new ShellCommandTable(); // for shell commands

        // the file system

        slash     = new Directory( "", null, null );
        User root = new User( "root", slash, "Rick Martin" );
        users.put( "root", root );
        slash.setOwner(root);
        userHomes = new Directory( "users", root, slash );

        // create, then start a command line login interpreter

        LoginInterpreter interpreter 
            = new LoginInterpreter( this, console );
        interpreter.CLILogin();
    }

    /**
     * The name of the host computer on which this system
     * is running.
     *
     * @return the host computer name.
     */

    public String getHostName()
    {
        return hostName;
    }

    /**
     * The name of this operating system.
     *
     * @return the operating system name.
     */

    public String getOS()
    {
        return os;
    }

    /**
     * The version number for this system.
     *
     * @return the version number.
     */

    public String getVersion()
    {
        return version;
    }

    /**
     * The directory containing all user homes for this system.
     *
     * @return the directory containing user homes.
     */

    public Directory getUserHomes()
    {
        return userHomes;
    }

    /**
     * The shell command table for this system.
     *
     * @return the shell command table.
     */

    public ShellCommandTable getCommandTable()
    {
        return commandTable;
    }

    /**
     * Look up a user by user name.
     *
     * @param username the user's name.
     * @return the appropriate User object. 
     */

    public User lookupUser( String username )  
    {
        return (User) users.get( username );
    }

    /**
     * Create a new User.
     *
     * @param userName the User's login name.
     * @param home her home Directory.
     * @param realName her real name.
     * @return newly created User.
     */

    public User createUser( String userName, Directory home,
                            String realName )
    {
        User newUser = new User( userName, home, realName );
        users.put( userName, newUser );
        return newUser;
    }

    /**
     * The Juno system may be given the following command line
     * arguments.
     * <pre>
     *
     * -e:         Echo all input (useful for testing).
     *
     * -version:   Report the version number and exit.
     *
     * [hostname]: The name of the host on which
     *             Juno is running (optional).
     * </pre>
     */

    public static void main( String[] args )
    {
        // Parse command line options

        boolean echoInput = false;
        String  hostName  = "mars";

        for (int i=0; i < args.length; i++) {
            if (args[i].equals("-version")) {
                System.out.println( os + " version " + version );
                System.exit(0);
            }
            if (args[i].equals("-e")) {
                echoInput = true;
            }
            else {
                hostName = args[i];
            }
        }

        // create a Juno instance, which will start itself

        new Juno( hostName, echoInput );
    }
}
