import urllib
import urlparse

from quixote import redirect, get_request
from quixote.directory import Directory

import lasso

from larpe.qommon.form import *
from larpe.qommon.misc import http_get_page

from larpe import errors
from larpe import misc
from larpe.errors import FormError
from larpe.hosts import Host
from larpe.admin.liberty_utils import *
#from larpe.filter import filter_misc
from larpe.admin.apache import write_apache2_vhosts

from menu import *

def check_minimal_configuration(form):
    misc.reload_cfg()
    # Check auth_url and auth_form_page_url
    auth_url = form.get_widget('auth_url').parse()
    auth_form_page_url = form.get_widget('auth_form_page_url').parse()
    if auth_url and auth_form_page_url:
        form.set_error('auth_form_page_url', _('"%s" and "%s" are incompatible. Only fill one of them.') % \
            (_('Authentication page'), _('Authentication form page')))
    # Check reversed_hostname and reversed_directory
    reversed_hostname = form.get_widget('reversed_hostname').parse()
    reversed_directory = form.get_widget('reversed_directory').parse()
    if reversed_hostname == misc.cfg['proxy_hostname'] and reversed_directory is None:
        form.set_error('reversed_hostname',
            _('You must either choose a different hostname from Larpe or specify a reversed directory'))
    

class HostUI:
    def __init__(self, host):
        self.host = host
        if self.host.reversed_hostname is None:
           self.host.reversed_hostname = get_request().get_server()

    def form_edit(self):
        # FIXME : homogeneise the size of the fields
        # FIXME : check what is entered in the fields
        form = Form(enctype='multipart/form-data')
        form.add(StringWidget, 'label', title = _('Site name'), required = True,
                size = 30, value = self.host.label)
        form.add(ValidUrlWidget, 'orig_site', title = _('Original site root address'), required = True,
                size = 50, value = self.host.orig_site)
        form.add(ValidUrlWidget, 'auth_url', title = _('Authentication page'),
                hint = _('If there is a separate authentication page'),
                required = False, size = 70, value = self.host.auth_url)
        form.add(ValidUrlWidget, 'auth_form_page_url',
                title = _('Authentication form page'),
                hint = _('If the authentication form is not in a separate page and not in the index page either'),
                required = False, size = 70, value = self.host.auth_form_page_url)
        form.add(ValidUrlWidget, 'logout_url', title = _('Logout address'), required = False,
                size = 70, value = self.host.logout_url)
        form.add(StringWidget, 'reversed_hostname', title = _('Reversed host name'),
                size = 30, required = True, value = self.host.reversed_hostname)
        form.add(StringWidget, 'reversed_directory', title = _('Reversed directory'),
                size = 30, required = False, value = self.host.reversed_directory)
        form.add(CheckboxWidget, 'use_ssl', title = _('Use SSL'),
                hint = _('This only affects the connection between the browser and Larpe'),
                value = self.host.use_ssl)
        form.add_submit('submit', _('Submit'))
        form.add_submit('cancel', _('Cancel'))
        return form

    def form_auto_detected_configuration(self):
        form = Form(enctype='multipart/form-data')
        form.add(RadiobuttonsWidget, 'auth_mode', title = _('Authentication mode'),
                options=[
                    ('form', _('Form'), 'form'),
                    ('http_basic', _('HTTP Basic'), 'http_basic'),
                ],
                sort=False,
                required = True,
                value = self.host.auth_mode)
        form.add(ValidUrlWidget, 'auth_check_url', title = _('Address where the authentication form must be sent'), required = False,
                size = 70, value = self.host.auth_check_url)
        form.add(StringWidget, 'login_field_name', title = _('Name of the login field'), required = False,
                size = 30, value = self.host.login_field_name)
        form.add(StringWidget, 'password_field_name', title = _('Name of the password field'), required = False,
                size = 30, value = self.host.password_field_name)
        form.add_submit('submit', _('Submit'))
        form.add_submit('cancel', _('Cancel'))
        return form        

    def form_advanced_configuration(self):
        form = Form(enctype='multipart/form-data')
        form.add(UrlOrAbsPathWidget, 'return_url', title = _('Return address'),
                hint = _('Where the user will be redirected after a successful authentication'),
                required = False, size = 50, value = self.host.return_url)
        form.add(UrlOrAbsPathWidget, 'root_url', title = _('Root address'),
                hint = _('Where the user will be redirected after a disconnection or an error'),
                required = False, size = 50, value = self.host.root_url)
        form.add(CheckboxWidget, 'send_hidden_fields', title=_('Send authentication form hidden fields'),
                value = self.host.send_hidden_fields)
        form.add(RadiobuttonsWidget, 'auth_system', title = _('Authentication system of the original site'),
                options=[
                    ('password', _('Check the existence of a password field'), 'password'),
                    ('match_text', _('Match some text to detect an authentication failure'), 'match_text'),
                ],
                sort=False,
                delim=htmltext('<br />'),
                value = self.host.auth_system)
        form.add(RegexStringWidget, 'auth_match_text', title = _('Text to match in case of authentication failure'),
                required = False, size = 50, value = self.host.auth_match_text)
        form.add_submit('submit', _('Submit'))
        form.add_submit('cancel', _('Cancel'))
        return form
        
    def submit_edit_form(self, form):
#        filter_misc.reload_cfg()
        metadata_cfg = {}
        for f in ('label', 'orig_site', 'auth_url', 'auth_form_page_url', 'logout_url', 'reversed_hostname',
                    'reversed_directory', 'use_ssl'):
            setattr(self.host, f, form.get_widget(f).parse())

        self.host.organization_name = self.host.label
        metadata_cfg['organization_name'] = self.host.organization_name

        self.host.name = self.host.label.lower().replace(' ', '_').replace("'", '_')

        if self.host.use_ssl:
            self.host.scheme = 'https'
        else:
            self.host.scheme = 'http'

        # Liberty Alliance / SAML parameters
        base_url = '%s://%s%s/liberty/%s/liberty' % (self.host.scheme,
                                                     self.host.reversed_hostname,
                                                     get_request().environ['SCRIPT_NAME'],
                                                     self.host.name)
        metadata_cfg['base_url'] = base_url
        self.host.base_url = base_url

        if lasso.SAML2_SUPPORT:
            saml2_base_url = '%s://%s%s/saml/%s/saml' % (self.host.scheme,
                                                         self.host.reversed_hostname,
                                                         get_request().environ['SCRIPT_NAME'],
                                                         self.host.name)
            metadata_cfg['saml2_base_url'] = saml2_base_url
            self.host.saml2_base_url = saml2_base_url

        provider_id = '%s/metadata' % base_url
        metadata_cfg['provider_id'] = provider_id
        self.host.provider_id = provider_id

        if lasso.SAML2_SUPPORT:
            saml2_provider_id = '%s/metadata' % saml2_base_url
            metadata_cfg['saml2_provider_id'] = saml2_provider_id
            self.host.saml2_provider_id = saml2_provider_id

        # Storage directories
        if self.host.reversed_directory is None:
            reversed_dir = 'None'
        else:
            reversed_dir = self.host.reversed_directory
        site_dir = os.path.join(get_publisher().app_dir, 'sp',
                    self.host.reversed_hostname, reversed_dir)
        user_dir = os.path.join(site_dir, 'users')
        token_dir = os.path.join(site_dir, 'tokens')
        for dir in (site_dir, user_dir, token_dir):
            if not os.path.isdir(dir):
                os.makedirs(dir)
        metadata_cfg['site_dir'] = site_dir
        self.host.site_dir = site_dir

        # Tweaking for larpe vhosts
        hostname_dir = misc.get_abs_path(os.path.join('..', self.host.reversed_hostname))
        if not os.path.exists(hostname_dir):
            os.mkdir(hostname_dir)
        misc.reload_cfg()
        misc.write_cfg(hostname_dir)

        # Generate SSL keys
        private_key_path = os.path.join(site_dir, 'private_key.pem')
        public_key_path = os.path.join(site_dir, 'public_key.pem')
        if not os.path.isfile(private_key_path) or not os.path.isfile(public_key_path):
            set_provider_keys(private_key_path, public_key_path)
            self.host.private_key = private_key_path
            self.host.public_key = public_key_path

        # Write metadatas
        metadata_path = os.path.join(site_dir, 'metadata.xml')
        file(metadata_path, 'w').write(get_metadata(metadata_cfg))
        self.host.metadata = metadata_path

        if hasattr(self.host, 'saml2_provider_id'):
            saml2_metadata_path = os.path.join(site_dir, 'saml2_metadata.xml')
            file(saml2_metadata_path, 'w').write(get_saml2_metadata(metadata_cfg))
            self.host.saml2_metadata = saml2_metadata_path

        # Use default idps
#        idp_dir = os.path.join(get_publisher().app_dir, 'idp')
#        self.host.idps = os.listdir(idp_dir)

        self.host.store()

        for attr in ('auth_check_url', 'login_field_name', 'password_field_name'):
            if not hasattr(self.host, attr) or not getattr(self.host, attr):
                self.auto_detect_configuration()
            
#        filter_misc.write_cfg()

        write_apache2_vhosts()

    def auto_detect_configuration(self):
        """Guess other SP parameters"""
        if self.host.auth_url is not None:
            # Separate auth page
            self.host.auth_form_url = self.host.auth_url
        else:
            if self.host.auth_form_page_url is not None:
                # Auth form is not on index page
                self.host.auth_form_url = self.host.auth_form_page_url
            else:
                # Auth form is on index page
                self.host.auth_form_url = self.host.orig_site
                
        # Get the authentication page
        status, page, auth_header = http_get_page(self.host.auth_form_url)
        if status == 401:
            if auth_header.startswith('Basic'):
                self.host.auth_mode = 'http_basic'
            else:
                self.host.auth_mode = 'unsupported'
            self.host.store()
            return

        if page is None:
            return
            #raise FormError, ('auth_check_url', '%s : %s' % (_('Failed to get page'), self.host.auth_form_url))

        self.host.auth_mode = 'form'

        # Get all forms
        regexp = re.compile("""<form.*?</form>""", re.DOTALL | re.IGNORECASE)
        found_forms = regexp.findall(page)
        if not found_forms:
            return
            #raise FormError, ('auth_check_url', '%s : %s' % (_('Failed to find any form'), self.host.auth_form_url))

        # Get the first form with a password field
        found = False
        for found_form in found_forms:
            regexp = re.compile("""<input[^>]*?type=["']?password["']?[^>]*?>""", re.DOTALL | re.IGNORECASE)
            if regexp.search(found_form) is not None:
                self.host.auth_form = found_form
                found = True
                break

        # If we found one, search for all needed information
        if not found:
            return
            #raise FormError, ('auth_check_url', _('Failed to find the authentication form'))
        
        # Get the action url of the form
        regexp = re.compile("""<form.*?action=["']?(.*?)["']?[\s>].*?>""", re.DOTALL | re.IGNORECASE)
        self.host.auth_check_url = regexp.findall(self.host.auth_form)[0]
        if not self.host.auth_check_url.startswith('http'):
            if self.host.auth_check_url.startswith('/'):
                if self.host.orig_site.startswith('https'):
                    orig_site_root = 'https://%s' % urllib.splithost(self.host.orig_site[6:])[0]
                else:
                    orig_site_root = 'http://%s' % urllib.splithost(self.host.orig_site[5:])[0]
                self.host.auth_check_url = orig_site_root + self.host.auth_check_url
            else:
                auth_form_url_tokens = self.host.auth_form_url.split('/')
                auth_form_url_tokens[-1] = self.host.auth_check_url
                self.host.auth_check_url = '/'.join(auth_form_url_tokens)
        
        # Get all inputs
        regexp = re.compile("""<input[^>]*?>""", re.DOTALL | re.IGNORECASE)
        inputs = regexp.findall(self.host.auth_form)

        # Get login field name
        try:
            regexp = re.compile("""<input[^>]*?type=["']?text["']?[^>]*?>""", re.DOTALL | re.IGNORECASE)
            text_fields = regexp.findall(self.host.auth_form)
            login_field = ''
            if text_fields:
                login_field = text_fields[0]
            else:
                for field in inputs:
                    if re.search("""type=["']?""", field, re.DOTALL | re.IGNORECASE) is None:
                        login_field = field
                        break
            regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE)
            self.host.login_field_name = regexp.findall(login_field)[0]
        except IndexError, e:
            self.host.login_field_name = None
            print 'Error handling login field : %s' % e

        # Get password field name
        try:
            regexp = re.compile("""<input[^>]*?type=["']?password["']?[^>]*?>""", re.DOTALL | re.IGNORECASE)
            password_field = regexp.findall(self.host.auth_form)[0]
            regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE)
            self.host.password_field_name = regexp.findall(password_field)[0]
        except IndexError, e:
            self.host.password_field_name = None
            print 'Error handling password field : %s' % e

        # Get the default value of all other fields
        self.host.other_fields = {}

        # Get hidden and submit fields
        regexp = re.compile("""<input[^>]*?type=["']?(?:hidden|submit)["']?[^>]*?>""", re.DOTALL | re.IGNORECASE)
        other_fields = regexp.findall(self.host.auth_form)
        for field in other_fields:
            try:
                regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE)
                name = regexp.findall(field)[0]
                regexp = re.compile("""value=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE)
                value = regexp.findall(field)[0]
                self.host.other_fields[name] = value
            except IndexError, e:
                continue

        # Get select fields
        # FIXME : check if one option is selected
        regexp = re.compile("""<select.*?</select>""", re.DOTALL | re.IGNORECASE)
        for field in regexp.findall(page):
            try:
                regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE)
                name = regexp.findall(field)[0]
                regexp = re.compile("""<option[^>]*?>(.*?)</option>""", re.DOTALL | re.IGNORECASE)
                value = regexp.findall(field)[0]
                self.host.other_fields[name] = value
            except IndexError, e:
                continue

#            print 'action : %s' % self.host.auth_check_url
#            print 'login field : %s' % self.host.login_field_name
#            print 'password field : %s' % self.host.password_field_name
#            print 'other fields : %s' % self.host.other_fields


        self.host.store()


    def submit_auto_detected_configuration_form(self, form):
        for f in ('auth_mode', 'auth_check_url', 'login_field_name', 'password_field_name'):
            value = form.get_widget(f).parse()
            setattr(self.host, f, value)

        if 'auth_mode' == 'form':
            if not self.host.auth_check_url.startswith('http'):
                if self.host.auth_check_url.startswith('/'):
                    if self.host.orig_site.endswith('/'):
                        self.host.auth_check_url = self.host.orig_site + self.host.auth_check_url[1:]
                    else:
                        self.host.auth_check_url = self.host.orig_site + self.host.auth_check_url
                else:
                    auth_form_url_tokens = self.host.auth_form_url.split('/')
                    auth_form_url_tokens[-1] = self.host.auth_check_url
                    self.host.auth_check_url = '/'.join(auth_form_url_tokens)

        self.host.store()


    def submit_advanced_configuration_form(self, form):
        for f in ('return_url', 'root_url', 'send_hidden_fields', 'auth_system', 'auth_match_text'):
            value = form.get_widget(f).parse()
            setattr(self.host, f, value)
            self.host.store()

class HostPage(Directory):
    _q_exports = ['', 'minimal_configuration', 'auto_detect_configuration', 'auto_detected_configuration', 'advanced_configuration', 'see_current_configuration', ('public_key.pem', 'public_key'), 'delete']

    def __init__(self, component):
        self.host = Host.get(component)
        self.host_ui = HostUI(self.host)
        get_response().breadcrumb.append((component + '/', self.host.label))

    def _q_index [html] (self):
        misc.reload_cfg()
        html_top('hosts', title = self.host.label)

        '<h2>%s</h2>' % _('Reverse Proxy')
        
        '<dl>'
        '<dt><a href="minimal_configuration">%s</a></dt> <dd>%s</dd>' % (
                _('Minimal Configuration'), _('Configure the minimum parameters to set up a reverse proxy for this site'))
        '<dt><a href="auto_detected_configuration">%s</a></dt> <dd>%s</dd>' % (
                _('Auto Detected Configuration'), _('Check the auto detected parameters and change them if necessary'))                
        '<dt><a href="advanced_configuration">%s</a></dt> <dd>%s</dd>' % (
                _('Advanced Configuration'), _("Configure advanced parameters if it doesn't work with minimal configuration"))
        '<dt><a href="see_current_configuration">%s</a></dt> <dd>%s</dd>' % (
                _('See Current Configuration'), _('See the current configuration of this host'))
        '</dl>'

#        if lasso.SAML2_SUPPORT:
#            '<h2>Liberty Alliance & SAML 2.0</h2>'
#            '<dl> <dt><a href="liberty_sp">%s</a></dt> <dd>%s</dd>' % (
#                    _('Service Provider'), _('Configure Liberty / SAML 2.0 parameters'))
#        else:
        '<h2>Liberty Alliance</h2>'
#            '<dl> <dt><a href="liberty_sp">%s</a></dt> <dd>%s</dd>' % (
#                    _('Service Provider'), _('Configure Liberty parameters'))

        '<dl>'
        metadata_url = '%s/metadata.xml' % self.host.base_url
        '<dt><a href="%s">%s</a></dt> <dd>%s</dd>' % (
                    metadata_url,
                    _('Service Provider Metadata'),
                    _('Download Service Provider ID-FF 1.2 Metadata file'))

#        metadata_url = '%s/metadata.xml' % self.host.saml2_base_url
#        '<dt><a href="%s">%s</a></dt> <dd>%s</dd>' % (
#                    metadata_url,
#                    _('Service Provider Metadata'),
#                    _('Download Service Provider SAML 2.0 Metadata file'))

        '<dt><a href="public_key.pem">%s</a></dt> <dd>%s</dd>' % (
                    _('Public key'),
                    _('Download Service Provider SSL Public Key file'))
        '</dl>'

    def minimal_configuration [html] (self):
        form = self.host_ui.form_edit()
        if form.get_widget('cancel').parse():
            return redirect('.')

        if form.is_submitted() and not form.has_errors():
            check_minimal_configuration(form)

        if form.is_submitted() and not form.has_errors():
            self.host_ui.submit_edit_form(form)
            return redirect('see_current_configuration')

        get_response().breadcrumb.append( ('minimal_configuration', _('Edit')) )
        html_top('hosts', title = _('Edit Host'))
        '<h2>%s</h2>' % _('Edit Host')

        form.render()

    def auto_detect_configuration (self):
        self.host_ui.auto_detect_configuration()
        return redirect('auto_detected_configuration')

    def auto_detected_configuration [html] (self, detect=False):
        form = self.host_ui.form_auto_detected_configuration()
        if form.get_widget('cancel').parse():
            return redirect('.')

        if not form.is_submitted() or form.has_errors():
            get_response().breadcrumb.append( ('auto_detected_configuration', _('Auto Detected Configuration')) )
            html_top('hosts', title = _('Auto Detected Configuration'))
            '<h2>%s</h2>' % _('Auto Detected Configuration')
            '<div><a href="auto_detect_configuration"><input type="button" value="%s" /></a> %s </div><br />' \
                % (_('Auto detect'), _('This will erase your custom modifications'))
            form.render()
        else:
            self.host_ui.submit_auto_detected_configuration_form(form)
            return redirect('see_current_configuration')

    def advanced_configuration [html] (self):
        form = self.host_ui.form_advanced_configuration()
        if form.get_widget('cancel').parse():
            return redirect('.')

        if not form.is_submitted() or form.has_errors():
            get_response().breadcrumb.append( ('advanced_configuration', _('Advanced Configuration')) )
            html_top('hosts', title = _('Advanced Configuration'))
            '<h2>%s</h2>' % _('Advanced Configuration')
            form.render()
        else:
            self.host_ui.submit_advanced_configuration_form(form)
            return redirect('see_current_configuration')

    def see_current_configuration [html] (self):
        get_response().breadcrumb.append( ('see_current_configuration', _('See Current Configuration')) )
        html_top('hosts', title = _('Current Host Configuration'))
        '<h2>%s</h2>' % _('Current Host Configuration')
        for attr in ('auth_check_url', 'login_field_name', 'password_field_name'):
            if not getattr(self.host, str(attr)):
                '<div class="errornotice">%s</div>' % _("This site is not fully configured yet. \
The following red fields don't have a correct value.")
                break
        # New url for this host
        url = '%s://%s%s/' % (self.host.scheme, self.host.reversed_hostname, get_request().environ['SCRIPT_NAME'])
        if self.host.reversed_directory is not None:
            url += '%s/' % self.host.reversed_directory
        '<div style="margin-bottom: 0.1em; font-weight: bold;">%s</div>' % _('New url for this host')
        '<div style="margin-left: 1em; margin-bottom: 0.3em;"><a href="%s">%s</a></div>' % (url, url)
        host_attrs_minimal = (
            ('label', _('Site name')),
            ('orig_site', _('Original site root address')),
            ('auth_url', _('Authentication page')),
            ('auth_form_page_url', _('Authentication form page')),
            ('logout_url', _('Logout address')),
            ('reversed_hostname', _('Reversed host name')),
            ('reversed_directory', _('Reversed directory')),
            ('use_ssl', _('Use SSL'))
        )
        host_attrs_auto = (
            ('auth_mode', _('Authentication mode')),
            ('auth_check_url', _('Address where the authentication form must be sent')),
            ('login_field_name', _('Name of the login field')),
            ('password_field_name', _('Name of the password field'))
        )
        host_attrs_advanced = (
            ('return_url', _('Return address')),
            ('root_url', _('Root address')),
            ('auth_system', _('Authentication system of the original site')),
            ('auth_match_text', _('Text to match in case of authentication failure')),
            ('send_hidden_fields', _('Send authentication form hidden fields'))
        )
        host_menus = (
            (host_attrs_minimal, '<a href="minimal_configuration">%s</a>' % _('Minimal Configuration')),
            (host_attrs_auto, '<a href="auto_detected_configuration">%s</a>' % _('Auto Detected Configuration')),
            (host_attrs_advanced, '<a href="advanced_configuration">%s</a>' % _('Advanced Configuration'))
        ) 
        for host_attrs, category in host_menus:
            '<h3>%s</h3>' % category
            for attr, name in host_attrs:
                color = 'black'
                if attr in ('auth_check_url', 'login_field_name', 'password_field_name') and \
                        not getattr(self.host, str(attr)):
                    color = 'red'
                '<div style="margin-bottom: 0.1em; font-weight: bold; color: %s;">%s</div>' % (color, name)
                '<div style="margin-left: 1em; margin-bottom: 0.3em; color: %s;">%s</div>' % \
                    (color, getattr(self.host, str(attr)))
                if getattr(self.host, str(attr)) == '':
                    '<br />'
        '<div class="buttons"><a href="."><input type="button" value="%s" /></a></div><br />' % _('Back')

    def public_key(self):
        response = get_response()
        response.set_content_type('text/plain')
        public_key = open(os.path.join(self.host.site_dir, 'public_key.pem')).read()
        return public_key

    def delete [html] (self):
        form = Form(enctype='multipart/form-data')
        form.widgets.append(HtmlWidget('<p>%s</p>' % _(
                        'You are about to irrevocably delete this host.')))
        form.add_submit('submit', _('Submit'))
        form.add_submit('cancel', _('Cancel'))
        if form.get_widget('cancel').parse():
            return redirect('..')
        if not form.is_submitted() or form.has_errors():
            get_response().breadcrumb.append(('delete', _('Delete')))
            html_top('hosts', title = _('Delete Host'))
            '<h2>%s : %s</h2>' % (_('Deleting Host'), self.host.label)
            form.render()
        else:
            self.host.remove_self()
            write_apache2_vhosts()
            return redirect('..')


class HostsDirectory(Directory):

    _q_exports = ['', 'new']

    def _q_index [html] (self):
        get_response().breadcrumb.append(('hosts/', _('Hosts')))
        html_top('hosts', title = _('Hosts'))
        """<ul id="nav-hosts-admin">
          <li><a href="new">%s</a></li>
        </ul>""" % _('New Host')

        '<ul class="biglist">'

        for host in Host.select(lambda x: x.name != 'larpe', order_by = 'label'):
            if not hasattr(host, str('scheme')):
                host.scheme = str('http')
            '<li>'
            '<strong class="label">%s</strong>' % host.label
            url = '%s://%s%s/' % (host.scheme, host.reversed_hostname, get_request().environ['SCRIPT_NAME'])
            if host.reversed_directory is not None:
                url += '%s/' % host.reversed_directory
            '<br /><a href="%s">%s</a>' % (url, url)
            '<p class="commands">'
            command_icon('%s/' % host.id, 'edit')
            command_icon('%s/delete' % host.id, 'remove')
            '</p></li>'
        '</ul>'

    def new [html] (self):
        if not os.path.isdir(os.path.join(get_publisher().app_dir, str('idp'))):
            html_top('hosts', title = _('New Host'))
            html = '<h2>%s</h2>' % _('New Host')
            html += 'You must <a href="%s/admin/settings/liberty_idp/">' % misc.get_root_url()
            html += 'configure an Identity Provider</a> first<br /><br />'
            html += '<a href="."><input type="button" value="%s" /></a>' % _('Back')
            return html

        get_response().breadcrumb.append(('hosts/', _('Hosts')))
        get_response().breadcrumb.append(('new', _('New')) )
        host = Host()
        host_ui = HostUI(host)
        form = host_ui.form_edit()
        if form.get_widget('cancel').parse():
            return redirect('.')

        if form.is_submitted() and not form.has_errors():
            check_minimal_configuration(form)
            label = form.get_widget('label').parse()
            for any_host in Host.select():
                if label == any_host.label:
                    form.set_error('label', _('An host with the same name already exists'))
                    break

        if form.is_submitted() and not form.has_errors():
            host_ui.submit_edit_form(form)
            return redirect('%s/see_current_configuration' % host.id)

        html_top('hosts', title = _('New Host'))
        '<h2>%s</h2>' % _('New Host')
        form.render()
    
    def _q_lookup(self, component):
        get_response().breadcrumb.append(('hosts/', _('Hosts')))
        return HostPage(component)
