"""quixote.init

Stuff for setting up Quixote prior to entering the main loop.

Note that if you're using ZODB, you must import ZODB before installing
Quixote's import hooks -- we're not sure why this is, but it is.  This
applies to 'init_quixote()' and 'install_imphooks()'.
"""

# created 2000/08/01, GPW

__revision__ = "$Id: init.py,v 1.6 2000/12/11 16:58:07 gward Exp $"

import sys
from types import StringType

def init_quixote ():
    install_imphooks()
    setup_logs()


def install_imphooks ():
    from quixote import imphooks
    imphooks.install()


def read_config_file (filename):
    from quixote.config import config
    config.read_file(filename)

def set_config (config):
    import quixote.config
    if not isinstance(config, quixote.config.Config):
        raise TypeError, "'config' must be a Config instance"
    quixote.config.config = config


class AutoflushFile:
    """A file-like object (output only) that flushes on every write."""

    def __init__ (self, file, mode="w"):
        if type(file) is StringType:
            file = open(file, mode)
        self.file = file

    def close (self):
        self.file.close()

    def write (self, str):
        self.file.write(str)
        self.file.flush()

    def writelines (self, list):
        self.file.writelines(list)
        self.file.flush()

    # Unnecessary due to the nature of the beast, but here for
    # a more complete implementation of the "file" interface.
    def flush (self):
        pass


_orig_stdout = None

def setup_logs ():
    """Redirect stdout: either to /dev/null or a debug log file
    (depending on whether DEBUG_LOG is defined in config.py).
    Saves the original stdout so it can be restored by 'restore_stdout()'.
    Note that this is not a real redirect in that it doesn't affect
    child processes; this just reassigns 'sys.stdout'.
    """
    from quixote.config import config
    global _orig_stdout

    if _orig_stdout is not None:
        raise RuntimeError, "you've already redirected stdout!"
    _orig_stdout = sys.stdout

    if config.debug_log is None:
        # If no debug log file is configured, debugging output goes
        # to the bit-bucket.
        sys.stdout = open('/dev/null', 'w')
    else:
        sys.stdout = AutoflushFile(config.debug_log, 'a')

def get_orig_stdout ():
    global _orig_stdout
    if _orig_stdout is None:
        raise RuntimeError, "redirect_stdout never called"
    return _orig_stdout

def shutdown_logs ():
    """Restore 'sys.stdout' to what it was before calling
    'setup_logs()'.
    """
    global _orig_stdout
    if _orig_stdout is None:
        raise RuntimeError, "'setup_logs()' never called"
    sys.stdout.close()
    sys.stdout = _orig_stdout

# aliases for backwards compatibility
redirect_stdout = setup_logs
restore_stdout = shutdown_logs        
