/*
 * Aleph Toolkit
 *
 * Copyright 1997,1998 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.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Hashtable;

/**
 * Rudimentary debugging support.  Dumps debugging info to a file.
 *
 * @author Michael Rubin
 * @author Maurice Herlihy
 * @date   March 1998
 **/

public class AlephDebug {
  /**
   * Window title
   **/
  static private String title = null;

  /**
   * Write message here
   **/
  static private PrintWriter log;

  /**
   * Table of interesting objects.
   **/
  private static Hashtable snap = new Hashtable(); // table of objects

  /**
   * Override default title.
   **/
  static public void setTitle (String newTitle) {
    title = newTitle;
  }

  /**
   * Send a line of output to debugging display.
   * @see aleph.Config
   * @parm msg text to display
   * @parm dump print stack trace?
   **/
  public static void println (String msg, boolean trace) {
    try {
      if (log == null) {        // don't open until user actually writes something
        if (title == null)
          title = Aleph.getProperty("aleph.label");
        log = new PrintWriter(new FileWriter(new File(Config.logDir, title + ".debug")));
      }
      log.println(msg);
      if (trace)
        printStackTrace(log);
      log.flush();
    } catch (Exception e) {
      Aleph.panic(e);
    }
  }
  /**
   * Send a line of output to debugging display.
   * @see aleph.Config
   * @parm msg text to display
   **/
  public static void println (String msg) {
    println(msg, false);
  }

  public static void printStackTrace (PrintWriter out) {
    try {
      ByteArrayOutputStream dump = new ByteArrayOutputStream();
      (new Throwable()).printStackTrace(new PrintWriter(dump));
      out.println(dump.toString());
    } catch (Exception e) {
      Aleph.panic(e);
    }
  }

  /**
   * Test an assertion, panic on failure.<br>
   * This is your brain on bugs.
   * @parm assertion test this!
   **/
  public static void assert (boolean assertion) {
    assert(assertion, "");
    }

  /**
   * Test an assertion, panic on failure.<br>
   * This is your brain on bugs.
   * @parm assertion test this!
   * @parm label informative note
   **/
  public static void assert (boolean assertion, String label) {
    if (!assertion) {
      Throwable t = new Throwable("ASSERTION FAILED: " + label);
      t.printStackTrace(System.out);
      t.printStackTrace(log);
      log.flush();
      System.exit(1);
    }
  }

  /**
   * Register interesting object.  This object will be part of any ``core
   * dump'' following a panic.
   * @param label helpful tag
   * @param object object to dump
   **/
  public static void register (String label, Object object) {
    snap.put(label, object);
  }

  /**
   * Write out snapshot of interesting objects.
   * @param writer when to send snapshot.
   **/
  public static void dump (PrintWriter writer) {
    for (Enumeration enum = snap.keys(); enum.hasMoreElements(); ) {
      Object key = enum.nextElement();
      Object object = snap.get(key);
      writer.println();
      writer.println(key);
      writer.print("\t");
      writer.println(object);
    }
  }

};

