# coding=utf-8

from mongoengine import StringField
from mongoengine import register_connection
from mongoengine.connection import _connection_settings, get_db

from .common import ModelDocument, MultipleDatabaseModelDocument
import session  # again implicit relative import due to circular issues, but we will try to remove this one

################################################################################
__all__ = ('Database',)


################################################################################
class Database(ModelDocument):
    meta = {
        'db_alias': 'admin_db',
        'collection': 'databases',
    }

    label = StringField(required=True, #TODO: make unique
        verbose_name='Label', help_text='The human-readable label for the database.')

    host = StringField(required=True, # TODO: change to URLField
        verbose_name='Host', help_text='The URL of the database\'s host.')

    dbname = StringField(required=True,
        verbose_name='Database Name', help_text='The internal Mongo name of the database.')

    username = StringField(required=False, db_field='user',
        verbose_name='Username', help_text='The username required to connect to the database.')

    password = StringField(required=False,
        verbose_name='Password', help_text='The password required to connect to the database.')

    auth_db = StringField(required=False,
        verbose_name='Authentication Database', help_text='The database to authenticate against.')

    copyright = StringField(required=False, default='Copyright &copy 2014, All rights reserved.',
        verbose_name='Copyright', help_text='The default copyright for content in the database.')

    def __unicode__(self):
        return unicode(self.label)

    @property
    def connection_alias(self):
        return str(self.id)

    def is_registered(self):
        return self.connection_alias in _connection_settings

    def register(self):
        if not self.is_registered():
            hostname, _, port = self.host.partition(':')
            register_connection(
                alias=self.connection_alias,
                host=hostname,
                port=int(port) if port else None,
                name=self.dbname,
                username=self.username,
                password=self.password,
                authentication_source=self.auth_db)

    def __enter__(self):
        self.register()
        # TODO: 'MultipleDatabaseModelDocument._subclasses' contains a list with all of the subclasses
        #  (including itself), but as strings; we need a way to get the actual class object, so it can
        #  be modified;
        #  maybe make a new metaclass to do it, but then it must fake that its 'my_metaclass'
        #  until then, we have to explicitly enumerate the classes, which is hard to maintain
        for cls in [MultipleDatabaseModelDocument, session.Session]:
            cls._db_alias = self.connection_alias
            cls._collection = None  # clear any cached collection
        # don't return anything

    def __exit__(self, exc_type, exc_value, traceback):
        # TODO: get rid of the explicit listing; see above
        for cls in [MultipleDatabaseModelDocument, session.Session]:
            cls._db_alias = self.connection_alias
            cls._collection = None  # clear any cached collection

    def to_pymongo(self):
        """"
        [deprecated]
        This is for temporary convenience, as all database access is migrated to models.

        This will be removed once the migration is complete, so please don't rely more than
        necessary upon it.
        """
        self.register()
        return get_db(self.connection_alias)


@@ -1099,25 +1099,8 @@
 lse,
- db_field='user',
 %0A   

Support for storing image database login credentials explicitly