# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import absolute_import
from django.conf.urls import patterns, url, include

from wiki.conf import settings
from wiki.core.plugins import registry
from wiki.views import article, accounts
from wiki.core.utils import get_class_from_str


class WikiURLPatterns(object):
    '''
    configurator for wiki urls.

    To customize, you can define your own subclass, either overriding
    the view providers, or overriding the functions that collect
    views.
    '''

    # basic views
    article_view_class = article.ArticleView
    article_create_view_class = article.Create
    article_delete_view_class = article.Delete
    article_deleted_view_class = article.Deleted
    article_dir_view_class = article.Dir
    article_edit_view_class = article.Edit
    article_preview_view_class = article.Preview
    article_history_view_class = article.History
    article_settings_view_class = article.Settings
    article_source_view_class = article.Source
    article_plugin_view_class = article.Plugin
    revision_change_view = article.ChangeRevisionView
    revision_merge_view = 'wiki.views.article.merge'

    search_view_class = settings.SEARCH_VIEW
    article_diff_view = 'wiki.views.article.diff'

    # account views
    signup_view_class = accounts.Signup
    login_view_class = accounts.Login
    logout_view_class = accounts.Logout

    def get_urls(self):
        urlpatterns = self.get_root_urls()
        urlpatterns += self.get_accounts_urls()
        urlpatterns += self.get_revision_urls()
        urlpatterns += self.get_article_urls()
        urlpatterns += self.get_plugin_urls()

        # This ALWAYS has to be the last of all the patterns since
        # the paths in theory could wrongly match other targets.
        urlpatterns += self.get_article_path_urls()
        return urlpatterns

    def get_root_urls(self):
        urlpatterns = patterns('',
            url('^$', self.article_view_class.as_view(), name='root', kwargs={'path': ''}),
            url('^create-root/$', article.CreateRootView.as_view(), name='root_create'),
            url('^missing-root/$', article.MissingRootView.as_view(), name='root_missing'),
            url('^_search/$', get_class_from_str(self.search_view_class).as_view(), name='search'),
            url('^_revision/diff/(?P<revision_id>\d+)/$', self.article_diff_view, name='diff'),
       )
        return urlpatterns

    def get_accounts_urls(self):
        urlpatterns = patterns('',
            url('^_accounts/sign-up/$', self.signup_view_class.as_view(), name='signup'),
            url('^_accounts/logout/$', self.logout_view_class.as_view(), name='logout'),
            url('^_accounts/login/$', self.login_view_class.as_view(), name='login'),
           )
        return urlpatterns

    def get_revision_urls(self):
        urlpatterns = patterns('',
            # This one doesn't work because it don't know where to redirect after...
            url('^_revision/change/(?P<article_id>\d+)/(?P<revision_id>\d+)/$', self.revision_change_view.as_view(), name='change_revision'),
            url('^_revision/preview/(?P<article_id>\d+)/$', self.article_preview_view_class.as_view(), name='preview_revision'),
            url('^_revision/merge/(?P<article_id>\d+)/(?P<revision_id>\d+)/preview/$', self.revision_merge_view, name='merge_revision_preview', kwargs={'preview': True}),
           )
        return urlpatterns

    def get_article_urls(self):
        urlpatterns = patterns('',
            # Paths decided by article_ids
            url('^(?P<article_id>\d+)/$', self.article_view_class.as_view(), name='get'),
            url('^(?P<article_id>\d+)/delete/$', self.article_delete_view_class.as_view(), name='delete'),
            url('^(?P<article_id>\d+)/deleted/$', self.article_deleted_view_class.as_view(), name='deleted'),
            url('^(?P<article_id>\d+)/edit/$', self.article_edit_view_class.as_view(), name='edit'),
            url('^(?P<article_id>\d+)/preview/$', self.article_preview_view_class.as_view(), name='preview'),
            url('^(?P<article_id>\d+)/history/$', self.article_history_view_class.as_view(), name='history'),
            url('^(?P<article_id>\d+)/settings/$', self.article_settings_view_class.as_view(), name='settings'),
            url('^(?P<article_id>\d+)/source/$', self.article_source_view_class.as_view(), name='source'),
            url('^(?P<article_id>\d+)/revision/change/(?P<revision_id>\d+)/$', self.revision_change_view.as_view(), name='change_revision'),
            url('^(?P<article_id>\d+)/revision/merge/(?P<revision_id>\d+)/$', self.revision_merge_view, name='merge_revision'),
            url('^(?P<article_id>\d+)/plugin/(?P<slug>\w+)/$', self.article_plugin_view_class.as_view(), name='plugin'),
           )
        return urlpatterns

    def get_article_path_urls(self):
        urlpatterns = patterns('',
            # Paths decided by URLs
            url('^(?P<path>.+/|)_create/$', self.article_create_view_class.as_view(), name='create'),
            url('^(?P<path>.+/|)_delete/$', self.article_delete_view_class.as_view(), name='delete'),
            url('^(?P<path>.+/|)_deleted/$', self.article_deleted_view_class.as_view(), name='deleted'),
            url('^(?P<path>.+/|)_edit/$', self.article_edit_view_class.as_view(), name='edit'),
            url('^(?P<path>.+/|)_preview/$', self.article_preview_view_class.as_view(), name='preview'),
            url('^(?P<path>.+/|)_history/$', self.article_history_view_class.as_view(), name='history'),
            url('^(?P<path>.+/|)_dir/$', self.article_dir_view_class.as_view(), name='dir'),
            url('^(?P<path>.+/|)_settings/$', self.article_settings_view_class.as_view(), name='settings'),
            url('^(?P<path>.+/|)_source/$', self.article_source_view_class.as_view(), name='source'),
            url('^(?P<path>.+/|)_revision/change/(?P<revision_id>\d+)/$', self.revision_change_view.as_view(), name='change_revision'),
            url('^(?P<path>.+/|)_revision/merge/(?P<revision_id>\d+)/$', self.revision_merge_view, name='merge_revision'),
            url('^(?P<path>.+/|)_plugin/(?P<slug>\w+)/$', self.article_plugin_view_class.as_view(), name='plugin'),
            # This should always go last!
            url('^(?P<path>.+/|)$', self.article_view_class.as_view(), name='get'),
           )
        return urlpatterns

    def get_plugin_urls(self):
        urlpatterns = patterns('',)
        for plugin in list(registry.get_plugins().values()):
            slug = getattr(plugin, 'slug', None)
            if slug:
                article_urlpatterns = plugin.urlpatterns.get('article', [])
                urlpatterns += patterns('',
                    url('^(?P<article_id>\d+)/plugin/' + slug + '/', include(article_urlpatterns)),
                    url('^(?P<path>.+/|)_plugin/' + slug + '/', include(article_urlpatterns)),
                )
                root_urlpatterns = plugin.urlpatterns.get('root', [])
                urlpatterns += patterns('',
                    url('^_plugin/' + slug + '/', include(root_urlpatterns)),
               )
        return urlpatterns

def get_pattern(app_name="wiki", namespace="wiki", url_config_class=None):
    """Every url resolution takes place as "wiki:view_name".
       You should not attempt to have multiple deployments of the wiki in a
       single Django project.
       https://docs.djangoproject.com/en/dev/topics/http/urls/#topics-http-reversing-url-namespaces
    """
    if url_config_class is None:
        url_config_classname=getattr(settings, 'URL_CONFIG_CLASS', None)
        if url_config_classname is None:
            url_config_class = WikiURLPatterns
        else:
            url_config_class = get_class_from_str(url_config_classname)
    urlpatterns = url_config_class().get_urls()
    return urlpatterns, app_name, namespace


######################
# PLUGINS
######################

from wiki.core.plugins.loader import load_wiki_plugins

load_wiki_plugins()


