
VIEWS = (

    ## crud
    'ListView',
    'CreateView',
    'UpdateView',
    'DeleteView',
    'DetailView',
    # 'DeleteViewCustomDeleteWarning',

    ## history
    'ArchiveIndexView',
    'DateDetailView',
    'DayArchiveView',
    'MonthArchiveView',
    'TodayArchiveView',
    'WeekArchiveView',
    'YearArchiveView',

    'RedirectView',
    'TemplateView',

    'FormView',
    'LoginView',
    'LogoutView',

    'PasswordChangeDoneView',
    'PasswordChangeView',
    'PasswordResetCompleteView',
    'PasswordResetConfirmView',
    'PasswordResetDoneView',
    'PasswordResetView',

)

## Order is importtant.
url_enforcements = (
    ( ('update', 'detail', 'delete',), '{name}/<str:pk>/', ),
    # ( ('archiveindex',), '', ),
    ( ('todayarchive',), 'today/', ),
    ( ('datedetail',  ), '<int:year>/<str:month>/<int:day>/<int:pk>/', ),
    ( ('dayarchive',  ), '<int:year>/<str:month>/<int:day>/', ),
    ( ('montharchive',), '<int:year>/<str:month>/' , ),
    ( ('weekarchive', ), '<int:year>/week/<int:week>/', ),
    ( ('yeararchive', ), '<int:year>/', ),
)

## Generate a Mapped name lise of the VIEWS, producing a list for direct
## name association:
    # 'list':'ListView',
    # 'create':'CreateView',
    # 'update':'UpdateView',
    # 'delete':'DeleteView',
    # 'detail':'DetailView',
MAPPED_NAMES = { x[:-4].lower(): x for x in VIEWS }

## Write the reverse of the MAPPED_NAMES, for class to friendly map:
    # ListView: list
MAPPED_CLASS = {y:x for x,y in MAPPED_NAMES.items()}


def crud():
    return (
        'list',
        'create',
        'update',
        'delete',
        'detail',
        )

def history():
    # Order is important
    return (
        'archiveindex',
        'todayarchive',
        'weekarchive',
        'datedetail',
        'dayarchive',
        'montharchive',
        'yeararchive',
    )

def tidy_enforcements(enforcements):
    url_parts = {}
    for names, enforced in enforcements:
        for n in names:
            url_parts[n] = enforced
    return url_parts


def render_defaults(names, parts):
    refs = {}
    res = {}
    for name, classname in names.items():
        refs['name'] = name
        refs['classname'] = classname
        live_part = parts.get(name, None)
        first = f'{name}/'
        part = ''
        if live_part is not None:
            part = live_part.format(**refs)
            first = ''
        res[name] = f'{first}{part}'
    return res


URL_PARTS = tidy_enforcements(url_enforcements)
URL_DEFAULTS = render_defaults(MAPPED_NAMES, URL_PARTS)

def get_url(name):
    return URL_DEFAULTS.get(name)

import inspect

def get_mapped_name(instance):
    mro = inspect.getmro(instance.__class__)
    for _c in mro:
        r = MAPPED_CLASS.get(_c.__name__)
        if r is not None:
            return r
