#!/usr/bin/env python
# -*- mode: python -*-
#
# Copyright (C) 2005 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

import os
import sys
import pwd
import tempfile
import pygtk; pygtk.require('2.0');
import gtk

from sabayon import util
from sabayon import config
from sabayon import debuglog
from sabayon import errors

tmp_readable_log_config_file = None

def readable_log_config_setup ():
    # The file which defines the configuration for the debug log may
    # only be readable by root.  So, we copy it to a world-readable
    # temporary file so that the helper processes can read it.

    global tmp_readable_log_config_file
    assert tmp_readable_log_config_file == None

    tmp_readable_log_config_file = tempfile.NamedTemporaryFile ()
    name = tmp_readable_log_config_file.name

    debuglog.debug_log_dump_configuration (tmp_readable_log_config_file)
    tmp_readable_log_config_file.flush ()

    os.chmod (name, 0644)

    util.set_readable_log_config_filename (name)

if __name__ == '__main__':
    def dprint (fmt, *args):
        debuglog.debug_log (False, debuglog.DEBUG_LOG_DOMAIN_ADMIN_TOOL, fmt % args)

    def mprint (fmt, *args):
        debuglog.debug_log (True, debuglog.DEBUG_LOG_DOMAIN_ADMIN_TOOL, fmt % args)

    util.init_gettext ()

    def show_error_dialog (primary_text, secondary_text):
        errordialog = gtk.MessageDialog (None,
                                         gtk.DIALOG_DESTROY_WITH_PARENT,
                                         gtk.MESSAGE_ERROR,
                                         gtk.BUTTONS_CLOSE,
                                         primary_text)
        errordialog.format_secondary_text (secondary_text)
        errordialog.run ()
        errordialog.destroy ()

    if os.geteuid () != 0:
        show_error_dialog (_("Your account does not have permissions to run the Desktop User Profiles tool"),
                           _("Administrator level permissions are needed to run this program because it can "
                             "modify system files."))
        sys.exit (1)

    if os.environ.has_key ("SABAYON_SESSION_RUNNING"):
        show_error_dialog (_("Desktop User Profiles tool is already running"),
                           _("You may not use Desktop User Profiles tool from "
                             "within a profile editing session"))
        sys.exit (1)

    try:
        pwd.getpwnam (config.PROTOTYPE_USER)
    except KeyError, e:
        show_error_dialog (_("User account '%s' was not found") % config.PROTOTYPE_USER,
                           _("Sabayon requires a special user account '%s' to be present "
                             "on this computer. Try again after creating the account (using, "
                             "for example, the 'adduser' command)") % config.PROTOTYPE_USER)
        sys.exit (1)

    from sabayon import profilesdialog

    log_filename = os.path.join (util.get_home_dir (), config.LOG_CONFIG_FILENAME)
    debuglog.debug_log_load_configuration (log_filename)

    util.set_admin_log_config_filename (log_filename)
    readable_log_config_setup ()

    # Go!

    try:
        mprint ("Creating profiles dialog")
        dialog = profilesdialog.ProfilesDialog ()
    except:
        errors.errors_log_fatal_error (debuglog.DEBUG_LOG_DOMAIN_ADMIN_TOOL,
                                       "Fatal exception while creating the profiles dialog; will exit abnormally.")
        debuglog.debug_log_current_exception (debuglog.DEBUG_LOG_DOMAIN_ADMIN_TOOL)
    else:
        # We put the call to gtk.main() *outside* the "try" block,
        # since exceptions thrown in callbacks will not get caught
        # here (i.e.  the C stack won't be unrolled when an
        # exception happens).
        mprint ("Starting main loop")
        gtk.main ()
        mprint ("Terminating main loop")

    if errors.errors_have_fatal_error ():
        mprint ("Exiting abnormally; dumping log due to a fatal error")
        log_filename = debuglog.debug_log_dump_to_dated_file (util.get_admin_log_config_filename ())
        sys.stderr.write ("Dumped debug log to %s\n" % log_filename)

        dialog = gtk.MessageDialog (parent = None,
                                    flags = 0,
                                    type = gtk.MESSAGE_ERROR,
                                    buttons = gtk.BUTTONS_CLOSE,
                                    message_format = (_("A fatal error has occurred.  You can help us fix the problem "
                                                        "by sending the log in %s to %s")
                                                      % (log_filename, config.BUG_TRACKING_SYSTEM)))
        dialog.run ()
        dialog.destroy ()
        sys.exit (util.EXIT_CODE_FATAL)
    elif errors.errors_have_recoverable_error ():
        mprint ("Exiting normally; dumping log due to a recoverable error")
        log_filename = debuglog.debug_log_dump_to_dated_file (util.get_admin_log_config_filename ())
        sys.stderr.write ("Dumped debug log to %s\n" % log_filename)

        dialog = gtk.MessageDialog (parent = None,
                                    flags = 0,
                                    type = gtk.MESSAGE_ERROR,
                                    buttons = gtk.BUTTONS_CLOSE,
                                    message_format = (_("Sabayon will now exit.  There were some recoverable errors, "
                                                        "and you can help us debug the problem "
                                                        "by sending the log in %s to %s")
                                                      % (log_filename, config.BUG_TRACKING_SYSTEM)))
        dialog.run ()
        dialog.destroy ()

        sys.exit (util.EXIT_CODE_RECOVERABLE)
    else:
        mprint ("Exiting normally")
        sys.exit (util.EXIT_CODE_NORMAL)
