
import byucc.jhdl.apps.Stimulator.Stimulator;
import byucc.jhdl.base.HWSystem;
import byucc.jhdl.base.Node;
import byucc.jhdl.base.TestBench;
import byucc.jhdl.base.Wire;
import byucc.jhdl.base.WireValueException;
import byucc.jhdl.Logic.Logic;
import java.util.ArrayList;

/** This is the final application (simulation only) for the
 * NetworkMonitor design.  This class demonstrates creating a custom
 * Broker object to manage the dealings of a complete, deployable
 * custom application.
 * @author Anthony L. Slade */
public class Monitor extends Logic implements TestBench {

  /** The set width of a packet */
  public static final int PACKETWIDTH = 5;
  /** The low-order index of the address portion of the packets */
  public static final int ADDRESS_LO = 0;
  /** The high-order index of the address portion of the packets */
  public static final int ADDRESS_HI = 4;
  /** The pre-defined width of a counter */
  public static final int COUNTERWIDTH = 16;

  /** Reads in values from the command line to set the parameters of
   * the HitCounterArray to be tested.  Also creates a GraphCanvas
   * view of the HitCounterArray counts. */
  public static void main( String[] args ) {
    if ( 1 > args.length )
      showUsage(1);

    // parse user input
    ArrayList toCountList = new ArrayList(),
      toBlockList = new ArrayList();
    ArrayList list = toCountList;
    for ( int vi = 0; vi < args.length; ++vi ) {
      if ( "-".equals(args[vi]) ) {
	if ( list == toBlockList ) // 2nd "-" found :(
	  showUsage(1);
	else
	  list = toBlockList;
      } else
	list.add(args[vi]);
    }
    // fill in the int arrays with parsed integer values
    int[] toCount = new int[ toCountList.size() ];
    for ( int ind = 0; ind < toCountList.size(); ++ind )
      try {
	toCount[ind] = Integer.parseInt( (String)toCountList.get(ind) );
      } catch ( NumberFormatException nfe ) {
	showUsage(1);
      }
    int[] toBlock = new int[ toBlockList.size() ];
    for ( int ind = 0; ind < toBlockList.size(); ++ind )
      try {
	toBlock[ind] = Integer.parseInt( (String)toBlockList.get(ind) );
      } catch ( NumberFormatException nfe ) {
	showUsage(1);
      }

    // build the TestBench and the design circuit
    HWSystem system = new HWSystem();
    Monitor monitor
      = new Monitor( system,
		     toCount,
		     toBlock );
    // put the design in a custom Broker to generate the interactive environment
    new MonitorBroker( system, toCount, toBlock );
  }

  /** Prints out the usage for the user to learn what the command line
   * should be
   * @param exitValue the return exit value for when the program
   * exits */
  public static void showUsage(int exitValue) {
    System.err.println( "TestMonitor usage:" );
    System.err.println( "  java TestMonitor "
			+"<count_value>+ - <block_value>+" );
    System.exit( exitValue );
  }

  /** Builds a Monitor TestBench
   * @param parent The HWSystem
   * @param toCount the numbers of the addresses to watch
   * @param toBlock the numbers of the addresses to block */
  public Monitor( Node parent, int[] toCount, int[] toBlock ) {
    super( parent,"Monitor" );
    new NetworkMonitor( this,
			toCount, toBlock,
			packetsIn = wire( PACKETWIDTH, "packetsIn"),
			ADDRESS_LO, ADDRESS_HI,
			restart = wire( 1, "restart" ),
			packetsOut = wire( PACKETWIDTH, "packetsOut"),
			COUNTERWIDTH );
    Stimulator stim = new Stimulator( this );
    stim.addWire( packetsIn );
    stim.addWire( restart );
  }

  // The input and output wires of the system
  protected Wire packetsIn, packetsOut, restart, countHit, blockHit;

} // end class Monitor
