"""
open/DurusWorks/qp/pub/common.py

Code for maintaining the global Publisher, and convenience functions
for operations that go through the publisher.
"""
from threading import current_thread
import sys

_publisher = {}  #  { int : Publisher }

def set_publisher(value):
    global _publisher
    assert current_thread().ident not in _publisher
    _publisher[current_thread().ident] = value

def clear_publisher():
    # Used in test scripts only.
    global _publisher
    if current_thread().ident in _publisher:
        del _publisher[current_thread().ident]

def get_publisher():
    return _publisher.get(current_thread().ident)

# All of the remaining functions here work through get_publisher().

def get_hit():
    return get_publisher().get_hit()

def get_request():
    return get_hit().get_request()

def get_fields():
    return get_publisher().get_fields()

def get_response():
    return get_hit().get_response()

def get_site():
    return get_publisher().get_site()

def get_path():
    return get_request().get_path()

def redirect(location, permanent=False):
    get_publisher().redirect(location, permanent=permanent)

def not_found(body=None):
    get_publisher().not_found(body=body)

def header(title, *args, **kwargs):
    return get_publisher().header(title, *args, **kwargs)

def footer(*args, **kwargs):
    return get_publisher().footer(*args, **kwargs)

def page(title, *content, **kwargs):
    return get_publisher().page(title, *content, **kwargs)

def respond(title, *content, **kwargs):
    return get_publisher().respond(title, *content, **kwargs)

def site_now():
    return get_publisher().get_time_zone().now()

def get_config_value(name, fallback=None):
    return get_publisher().configuration.get(name, fallback)

def complete_path(path):
    return get_publisher().complete_path(path)


# The remaining are for sites using DurusPublisher.

def get_session():
    return get_hit().get_session()

def get_user():
    return get_session().get_effective_user()

def ensure_signed_in():
    # protect against recursion
    frame =  sys._getframe()
    frame = frame.f_back
    while frame:
        if frame.f_code.co_name == 'ensure_signed_in':
            return
        frame = frame.f_back
    return get_publisher().ensure_signed_in()

def get_connection():
    return get_publisher().get_connection()

def get_users():
    return get_publisher().get_users()

def format_date(date):
    return get_publisher().format_date(date)

def format_date_time(date_time):
    return get_publisher().format_date_time(date_time)

def format_user(user):
    return get_publisher().format_user(user)
