from Defaults import *

import sys

import lasso
if not hasattr(lasso, 'SAML2_SUPPORT'):
    lasso.SAML2_SUPPORT = False

try:
    from larpe_cfg import *
except ImportError:
    pass

import os
import time
import lasso
import imp
import __builtin__
__builtin__.__dict__['_'] = lambda x: x

import gettext, locale

translations = {
    'en': gettext.NullTranslations(),
}

for lang in ['fr']:
    try:
        translations[lang] = gettext.translation('larpe', languages=[lang])
    except IOError:
        pass
__builtin__.__dict__['N_'] = lambda x: x

from quixote import enable_ptl
from quixote.publish import Publisher, get_response
enable_ptl()

import misc

import errors
import logger
import sessions

import roles
import users

import template
from root import RootDirectory

extra_dirs = []
def load_extra_items():
    global extra_dirs

    extra_dir = os.path.join(os.path.dirname(__file__), 'extra')
    if len(extra_dirs) == 0:
        extra_dirs = [extra_dir]

    for extra_dir in extra_dirs:
        if not os.path.exists(extra_dir):
            continue
        sys.path.append(extra_dir)
        for filename in os.listdir(extra_dir):
            if not filename.endswith('.py'):
                continue
            modulename = filename[:-3]
            fp, pathname, description = imp.find_module(modulename, [extra_dir])
            try:
                imp.load_module(modulename, fp, pathname, description)
            except:
                raise
                logger.warn('failed to load extra module: %s' % modulename)
                if fp:
                    fp.close()


class LarpePublisher(Publisher):
    def format_publish_error(self, exc):
        get_response().filter = {}
        if isinstance(exc, errors.AccessError) and hasattr(exc, 'render'):
            return exc.render()
        return errors.format_publish_error(exc)

    def finish_failed_request(self):
        result = Publisher.finish_failed_request(self)
        try:
            logger.error('internal server error')
        except:
            pass
        if not self.config.display_exceptions == 'text-in-html':
            return result
        # result is here the text output
        get_response().set_header("Content-Type", "text/html") # set back content-type
        (exc_type, exc_value, tb) = sys.exc_info()
        if exc_type is NotImplementedError:
            return template.error_page(
                _('This feature is not yet implemented.'),
                error_title = _('Internal Server Error'),
                exception = result)
        else:
            return template.error_page(
                _('The server encountered an internal error and was unable to complete your request.'),
                error_title = _('Internal Server Error'),
                exception = result)

    def filter_output(self, request, output):
        response = get_response()
        if response.content_type != 'text/html':
            return output
        if not hasattr(response, 'filter'):
            return output
        return template.decorate(output, response)

    def install_lang(self, lang = None):
        if lang is None:
            gettext.install('larpe') # will use environment variable to get language
        else:
            translations[lang].install()
        _1 = _ 
        __builtin__.__dict__['_'] = lambda x: unicode(_1(str(x)), 'utf-8').encode('iso-8859-1')
        __builtin__.__dict__['_1'] = _1

    def set_config(self):
        misc.reload_cfg()
        debug_cfg = misc.cfg.get('debug', {})
        self.logger.error_email = debug_cfg.get('error_email')
        self.config.display_exceptions = debug_cfg.get('display_exceptions')
        self.config.form_tokens = True
        if debug_cfg.get('logger', False):
            logger.enable()
        else:
            logger.disable()

    def try_publish(self, request): 
        lang = misc.cfg.get('language', {}).get('language', None)
        if lang == 'HTTP':
            lang = None
            accepted_languages = request.get_header('Accept-Language')
            if accepted_languages:
                accepted_languages = [x.strip() for x in accepted_languages.split(',')]
                # forget about subtag and quality value
                accepted_languages = [x.split('-')[0] for x in accepted_languages]
                for l in accepted_languages:
                    if l in translations.keys():
                        lang = l
                        break
        self.install_lang(lang)
        return Publisher.try_publish(self, request)


class LarpeVHostPublisher(LarpePublisher):
    def try_publish(self, request):
        self.app_dir = os.path.join(APP_DIR, request.get_server().split(':')[0])
        misc.reload_cfg()
        if misc.cfg.has_key('proxy_hostname'):
            self.app_dir = os.path.join(APP_DIR, misc.cfg['proxy_hostname'])
        if not os.path.exists(self.app_dir):
            os.mkdir(self.app_dir)
        self.set_config()
        return LarpePublisher.try_publish(self, request)


def create_publisher(publisher_class = LarpePublisher):
    load_extra_items()
    publisher = publisher_class(RootDirectory(),
            session_cookie_name = 'larpe',
            session_cookie_path = '/',
            error_log = ERROR_LOG)
    publisher.app_dir = APP_DIR
    publisher.data_dir = DATA_DIR
    if not os.path.exists(publisher.app_dir):
        os.mkdir(publisher.app_dir)
    publisher.set_session_manager(sessions.StorageSessionManager())
    publisher.set_config()
    return publisher

def create_vhost_publisher():
    return create_publisher(LarpeVHostPublisher)
