import os
from shutil import rmtree

from quixote import get_request

import misc
from storage import StorableObject
from Defaults import APP_DIR

class Host(StorableObject):
    _names = 'hosts'

    # Main settings
    label = None
    name = None
    orig_site = None
    new_url = None
    scheme = None
    auth_url = None
    auth_form_places = 'form_once'
    auth_form_page_url = None
    auth_form = None
    auth_form_url = None
    logout_url = None
    reversed_hostname = None
    reversed_directory = None
    organization_name = None
    use_ssl = False
    private_key = None
    public_key = None
    site_dir = None

    # Auto detected settings
    auth_mode = 'form'
    auth_form_action = None
    auth_check_url = None
    login_field_name = None
    password_field_name = None
    select_fields = {}
    post_parameters = {}
    http_headers = {}

    # Advanced settings
    return_url = '/'
    root_url = '/'
    auth_system = 'password'
    auth_match_text = ''
    send_hidden_fields = True
    initiate_sso_url = None
    redirect_root_to_login = False

    # Other attributes
    provider_id = None
    # Default value that indicates the proxy (if configured) is not disabled for this host yet
    use_proxy = True

    valid_username = None
    valid_password = None

    # Plugins
    # If name is set to None, use the default site authentication class
    site_authentication_plugin = None

    def get_host_from_url(cls):
        try:
            host = list(Host.select(lambda x: x.name == misc.get_proxied_site_name()))[0]
            if hasattr(host, 'site_authentication_instance'):
                del host.site_authentication_instance
            return list(Host.select(lambda x: x.name == misc.get_proxied_site_name()))[0]
        except Exception, e:
            return None
    get_host_from_url = classmethod(get_host_from_url)

    def get_host_with_provider_id(cls, provider_id):
        try:
            return list(Host.select(lambda x: x.provider_id == provider_id))[0]
        except:
            return None
    get_host_with_provider_id = classmethod(get_host_with_provider_id)

    def get_root_url(self):
        if self.root_url.startswith('/'):
            if self.reversed_directory:
                return '%s/%s%s' % (get_request().environ['SCRIPT_NAME'], self.reversed_directory, self.root_url)
            else:
                return '%s%s' % (get_request().environ['SCRIPT_NAME'], self.root_url)
        # In this case, must be a full url
        return self.root_url

    def get_return_url(self):
        if self.return_url.startswith('/'):
            if self.reversed_directory:
                return '%s/%s%s' % (get_request().environ['SCRIPT_NAME'], self.reversed_directory, self.return_url)
            else:
                return '%s%s' % (get_request().environ['SCRIPT_NAME'], self.return_url)
        # In this case, must be a full url
        return self.return_url

    def __cmp__(self, other):
        hostname_cmp = cmp(self.reversed_hostname, other.reversed_hostname)
        if hostname_cmp != 0:
            return hostname_cmp
        return cmp(self.reversed_directory, other.reversed_directory)

    def remove_object(cls, id):
        raise NotImplementedError()
    remove_object = classmethod(remove_object)

    def remove_self(self):
        # Main configuration file
        StorableObject.remove_self(self)
        # Other generated files
        if self.site_dir and os.path.exists(self.site_dir):
            rmtree(self.site_dir, ignore_errors=1)
            # Also remove hostname directory if empty (meaning there was no other subdirectory for this hostname)
            try:
                os.rmdir('/'.join(self.site_dir.split('/')[:-1]))
            except OSError:
                pass
        # Virtual host directory
        if self.reversed_hostname:
            dir = os.path.join(APP_DIR, self.reversed_hostname)
            if os.path.exists(dir):
                rmtree(dir, ignore_errors=1)

