#! /usr/bin/env python
# -*- coding: UTF-8 -*-

import sys
import traceback


def pretty_excepthook(mytype, value, traceb):

    """ beautified exception output """
    # we should __NEVER__ throw

    # first print everything to sys.stderr, we'll try later to display a
    # graphical error message
    # enable i18n if it's safe enough

    sys.stdout.flush()
    sys.stderr.flush()

    sys.stderr.write('\n')
    print >> sys.stderr, 'cut here'.center(75).replace(' ', '-')

    msg = """Uncaught exception (%s) \"%s\"
Please report any __real__ bug on http://bugzilla.gnome.org/enter_bug.cgi?product=gDesklets
You may find help on http://gnomesupport.org/forums/viewforum.php?f=23""" % (mytype, value)

    if issubclass(mytype, ImportError):

        msg += """
This error may occur because your system doesn't provide all required dependencies.
Please check carefully your setup before reporting any bug."""

    print >> sys.stderr, msg

    sys.stderr.write('\n')
    traceback.print_exception(mytype, value, traceb)
    sys.stderr.write('\n')

    trace = traceb

    while trace.tb_next:
        trace = trace.tb_next

    stack = []

    frame = trace.tb_frame

    while frame:
        stack.append(frame)
        frame = frame.f_back

    # only print the last 3 ^W^W^W all frames
    for item in stack[::-1]:

        print >> sys.stderr, "Frame [%s] in '%s:%d'" % \
            (item.f_code.co_name, item.f_code.co_filename, item.f_lineno)

        for key, value in item.f_locals.items():
            print >> sys.stderr, "    %s = %s" % (key, repr(value))

        sys.stderr.write('\n')


    print >> sys.stderr, 'end cut'.center(75).replace(' ', '-')
    print >> sys.stderr, 'Now exiting ...'
    sys.stdout.flush()
    sys.stderr.flush()


# this is not really useful at the moment; thus it's disabled
#sys.excepthook = pretty_excepthook


# set up i18n
from utils import i18n
import __builtin__
__builtin__._ = i18n.Translator("gdesklets")


# setup GTK
try:
    import pygtk
    pygtk.require("2.0")
except StandardError:
    print _("You need a recent version of PyGTK to run this program.")
    sys.exit(1983)


import os


def check_xserver():

    """ Check for running X server """

    if ("DISPLAY" not in os.environ):
        print _("Could not find X display.")
        sys.exit(1)


def check_user():

    """ Check if user starts gdesklets as root """

    if (os.getuid() == 0):
        print _("You must NOT run gDesklets as super user (root).")
        sys.exit(1)


def detach_as_daemon():

    """
    Performs the UNIX double fork to detach as a daemon process as described at
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731 and
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
    """

    try:
        pid = os.fork()
        if (pid > 0):
            os._exit(0)

        os.chdir("/")
        os.setsid()

        pid = os.fork()
        if (pid > 0):
            os._exit(0)

    except StandardError:
        print _("Could not fork daemon.")
        sys.exit(1)



def write_pid():

    import main
    import os
    import atexit
    
    f = open(main.PID_PATH, 'w')
    print >>f, os.getpid()
    f.close() # ensure it's written NOW

    atexit.register(os.remove, main.PID_PATH)



def redirect_to_logfile():

    """
    Redirects stdout and stderr to the given logfile and stdin to /dev/null.
    """

    from main import LOGFILE
    from utils.logger import SyncWriter

    out_log = file(LOGFILE, "w", 0)
    dev_null = file("/dev/null", "r")

    sys.stderr = sys.stdout = SyncWriter(out_log)
    sys.stdin = dev_null

    # dummy write
    print "The log file is located in %s\n" % (LOGFILE,)
    sys.stdout.flush()


def gdesklets_main():

    """ gdesklets main function to start """

    # prepare gdesklets (locale, signals, program_init)
    from main import init
    init()


    # build our sockets, trayicon and start them
    from main.Starter import Starter
    Starter()


    # enter gtk's mainloop
    import gtk
    gtk.main()


check_xserver()
check_user()
detach_as_daemon()
write_pid()
redirect_to_logfile()
gdesklets_main()
