#!/usr/bin/env python

__requires__ = 'TurboGears>=1.0.4.4'
import pkg_resources

import os, sys
from os.path import *
import imp

from flupconfig import code_dir, package_name

# -- START USER EDIT SECTION
# -- Users might need to edit this section --
root_class_name = package_name+'.controllers.Root' # (Required) The fully qualified Root class name.
project_module_name = package_name+'.config'      # (Required) The config module name.
log_dir = join(code_dir,'log')

sys.path.append(code_dir)

# Make sure its requirements get satisfied
package = __import__(package_name)
try:
    imp.find_module('commands', package.__path__)
except ImportError as e:
    __import__(package_name+'.command')
else:
    __import__(package_name+'.commands')

# -- END USER EDIT SECTION

# We do this here, not before the user stuff, in case 
# importing package_name.commands is important
pkg_resources.require("flup")

try:
    sys.stdout = open(join(log_dir, 'stdout.log'),'a')
    sys.stderr = open(join(log_dir, 'stderr.log'),'a')

    from logging import FileHandler
    import logging.handlers
    import commands
    class UnbufferedFileHandler(FileHandler):
        def emit(self, *args, **kw):
            FileHandler.emit(self, *args, **kw)
            self.flush()
            commands.getoutput('fs flush '+self.baseFilename)
    logging.handlers.UnbufferedFileHandler = UnbufferedFileHandler

    import turbogears
    import cherrypy

    print >> sys.stdout, "starting with basename %s" % basename(__file__)

    def tg_init():
        """ Checks for the required data and initializes the application. """

        global code_dir
        global root_class_name
        global project_module_name
        last_mark = 0

        # Input checks
        if not code_dir or not isdir(code_dir):
            raise ValueError("""The code directory setting is missing.
                                The fastcgi code will be unable to find
                                the TG code without this setting.""")

        if not root_class_name:
            raise ValueError("""The fully qualified root class name must
                                be provided.""")

        last_mark = root_class_name.rfind('.')

        if (last_mark < 1) or (last_mark + 1) == len(root_class_name):
            raise ValueError("""The user-defined class name is invalid.
                                Please make sure to include a fully
                                qualified class name for the root_class
                                value (e.g. wiki20.controllers.Root).""")


        print >> sys.stdout, "code dir: %s, log_dir: %s" % (code_dir, log_dir)

        if exists(join(code_dir, "setup.py")):
            print >> sys.stdout, "About to update config from %s" % join(code_dir, "dev.cfg")
            turbogears.update_config(configfile=join(code_dir, "dev.cfg"),modulename=project_module_name)
        else:
            print >> sys.stdout, "About to update config from %s" % join(code_dir, "prod.cfg")
            turbogears.update_config(configfile=join(code_dir, "prod.cfg"),modulename=project_module_name)

        # Parse out the root class information for Cherrypy Root class.
        package_name = root_class_name[:last_mark]
        class_name = root_class_name[last_mark+1:]
        print >> sys.stdout, "from %s import %s as Root" % (package_name,
                                                            class_name)
        exec('from %s import %s as Root' % (package_name, class_name))
        cherrypy.root = Root()

    # Main section -

    # Initialize the application, then start the server.
    print >> sys.stdout, "Before tg_init()"
    tg_init()
    
    print >> sys.stdout, "Before cherrypy.server.start()"
    sys.stdout.flush()
    cherrypy.server.start(initOnly=True, serverClass=None)
    print >> sys.stdout, "After cherrypy.server.start()"
    sys.stdout.flush()

    print >> sys.stdout, "before import cherrypy/wsgiapp"
    from cherrypy._cpwsgi import wsgiApp
    print >> sys.stdout, "Before wsgiserver(application=wsgiapp).run()"
    sys.stdout.flush()
except Exception,e:
    from flup.server.fcgi import WSGIServer
    from traceback import format_exception
    import pwd,socket
    tup = sys.exc_info()
    def errApp(environ, start_response):
        start_response('500 Flup Error', [('Content-Type', 'text/plain')],
                       sys.exc_info())

        for l in format_exception(*tup):
            yield l
        whoami = pwd.getpwuid(os.getuid())[0]
        hostname = socket.gethostname()
        yield "To restart: ssh %s@%s killall -u %s python\n" % (whoami,
                                                                hostname,
                                                                whoami)
    errserver = WSGIServer(errApp)
    errserver.run()
else:
    from flup.server.fcgi import WSGIServer
    server = WSGIServer(wsgiApp)
    server.run()
    print >> sys.stdout, "After wsgiserver(application=wsgiapp).run()"
    sys.stdout.flush()
