#
# Copyright 2001 by Object Craft P/L, Melbourne, Australia.
#
# LICENCE - see LICENCE file distributed with this software for details.
#

import urlparse

from albatross.template import Template
from albatross.context import CachingTemplateLoaderMixin, PickleSignMixin,\
     _caller_globals
from albatross.app import Application, PageModuleMixin, SimpleAppContext,\
     SessionAppContext
from albatross.session import SessionServerAppMixin


class RandomPageModuleMixin(PageModuleMixin):

    def load_page(self, ctx):
        # Get page name from request URI
        uri = ctx.request.get_uri()
        page = self.get_page_from_uri(ctx, uri)
        if not page:
            ctx.redirect(self.start_page())

        # Try to load the page module
        self.__page_found = 1
        try:
            self.load_page_module(ctx, page)
        except ImportError, e:
            if not str(e).endswith(page):
                raise
            ctx.locals.page_name = page
            self.__page_found = 0
        if self.__page_found:
            self.page_enter(ctx)

    def get_page_from_uri(self, ctx, uri):
        try:
            base_path = urlparse.urlparse(self.base_url())[2]
            uri_path = urlparse.urlparse(uri)[2]
            # Fixup base_path to end with a '/' so that it can be used as
            # a root path.
            if not base_path.endswith('/'):
                base_path =  base_path + '/'
            return uri_path.split(base_path, 1)[1]
        except IndexError:
            return None

    def load_badurl_template(self, ctx):
        return Template(ctx, '<internal>',
'''<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
 <head>
  <title>404 Not Found</title>
 </head>
 <body>
  <h1>Oops!</h1>
   URL <al-value expr="page_name"> was not found on this server.<p>
 </body>
</html>
''')

    def page_enter(self, ctx):
        if self.__page_found:
            return PageModuleMixin.page_enter(self, ctx, ())
        return None

    def process_request(self, ctx):
        if self.__page_found:
            return PageModuleMixin.process_request(self, ctx)
        return None

    def display_response(self, ctx):
        if self.__page_found:
            PageModuleMixin.display_response(self, ctx)
        else:
            # Display error page - no page module so use the mainline
            # globals
            templ = self.load_badurl_template(ctx)
            ctx.set_globals(_caller_globals('run'))
            templ.to_html(ctx)

class RandomModularApp(PickleSignMixin,
                       Application,
                       CachingTemplateLoaderMixin,
                       RandomPageModuleMixin):
    def __init__(self, base_url, page_path, start_page, secret):
        PickleSignMixin.__init__(self, secret)
        Application.__init__(self, base_url)
        CachingTemplateLoaderMixin.__init__(self, page_path)
        RandomPageModuleMixin.__init__(self, page_path, start_page)

    def create_context(self):
        return SimpleAppContext(self)


# Same as RandomModularApp with server-side session support
class RandomModularSessionApp(PickleSignMixin,
                              Application,
                              CachingTemplateLoaderMixin,
                              RandomPageModuleMixin,
                              SessionServerAppMixin):

    def __init__(self, base_url, page_path, start_page, secret,
                 session_appid, session_server = 'localhost', server_port = 34343, session_age = 1800):
        PickleSignMixin.__init__(self, secret)
        Application.__init__(self, base_url)
        CachingTemplateLoaderMixin.__init__(self, page_path)
        RandomPageModuleMixin.__init__(self, page_path, start_page)
        SessionServerAppMixin.__init__(self, session_appid, session_server, server_port, session_age)

    def create_context(self):
        return SessionAppContext(self)
