from django import db as django_db
from django.conf import settings
from django.core import signals

class ReadOnlyConnection(object):
    """
    This class constructs a new connection to the DB using the read-only
    credentials from settings.  It reaches into some internals of
    django.db.connection which are undocumented as far as I know, but I believe
    it works across many, if not all, of the backends.
    """
    _the_instance = None

    # support singleton
    @classmethod
    def get_connection(cls):
        if cls._the_instance is None:
            cls._the_instance = ReadOnlyConnection()
        return cls._the_instance


    @classmethod
    def set_globally_disabled(cls, disabled):
        """
        When globally disabled, the ReadOnlyConnection will simply pass through
        to the global Django connection.
        """
        if disabled:
            cls._the_instance = DummyReadOnlyConnection()
        else:
            cls._the_instance = None


    def __init__(self):
        self._connection = None


    def _open_connection(self):
        if self._connection is not None:
            return
        self._save_django_state()
        self._connection = self._get_readonly_connection()
        self._restore_django_state()


    def _save_django_state(self):
        self._old_connection = django_db.connection.connection
        _default_db = settings.DATABASES['default']
        self._old_host = _default_db['HOST']
        self._old_username = _default_db['USER']
        self._old_password = _default_db['PASSWORD']


    def _restore_django_state(self):
        django_db.connection.connection = self._old_connection
        _default_db = settings.DATABASES['default']
        _default_db['HOST'] = self._old_host
        _default_db['USER'] = self._old_username
        _default_db['PASSWORD'] = self._old_password


    def _get_readonly_connection(self):
        _default_db = settings.DATABASES['default']
        _default_db['HOST'] = _default_db['READONLY_HOST']
        _default_db['USER'] = _default_db['READONLY_USER']
        _default_db['PASSWORD'] = _default_db['READONLY_PASSWORD']
        reload(django_db)
        # cursor() causes a new connection to be created
        cursor = django_db.connection.cursor()
        assert django_db.connection.connection is not None
        return django_db.connection.connection


    def set_django_connection(self):
        assert (django_db.connection.connection != self._connection or
                self._connection is None)
        self._open_connection()
        self._old_connection = django_db.connection.connection
        django_db.connection.connection = self._connection


    def unset_django_connection(self):
        assert self._connection is not None
        assert django_db.connection.connection == self._connection
        django_db.connection.connection = self._old_connection


    def cursor(self):
        self._open_connection()
        return self._connection.cursor()


    def close(self):
        if self._connection is not None:
            assert django_db.connection.connection != self._connection
            self._connection.close()
            self._connection = None


class DummyReadOnlyConnection(object):
    """
    A dummy version which passes queries straight to the global Django
    connection.
    """

    def __init__(self):
        self._is_set = False


    def set_django_connection(self):
        assert not self._is_set
        self._is_set = True


    def unset_django_connection(self):
        assert self._is_set
        self._is_set = False


    def cursor(self):
        return django_db.connection.cursor()


    def close(self):
        pass


# convenience
def connection():
    return ReadOnlyConnection.get_connection()


# close any open connection when request finishes
def _close_connection(**unused_kwargs):
    connection().close()
signals.request_finished.connect(_close_connection)
