import logging

import django.core.handlers.wsgi
import django.core.management

from mini_buildd import util

LOG = logging.getLogger(__name__)


class WebApp(django.core.handlers.wsgi.WSGIHandler):
    """mini-buildd's web application"""

    def __init__(self):
        LOG.debug("Generating web application...")
        super().__init__()

        LOG.debug("Migrating database (migrate)...")
        try:
            django.core.management.call_command("migrate", interactive=False, run_syncdb=True, verbosity=0)
        except django.db.OperationalError as e:
            LOG.warning(f"OperationalError on migrate ({e}). Retrying with '--fake-initial'...")
            django.core.management.call_command("migrate", interactive=False, run_syncdb=True, fake_initial=True, verbosity=0)

        # django 1.8 no longer per default runs this; Doing this once, manually
        LOG.debug("Run django internal checks (check)...")
        django.core.management.call_command("check")

        # For temporary debugging/check settings only
        # LOG.debug(django.core.management.call_command("diffsettings", verbosity=0, output="unified"))

    @classmethod
    def set_admin_password(cls, password):
        """
        Set the password for the administrator

        :param password: The password to use.
        :type password: string
        """
        # This import needs the django app to be already configured (since django 1.5.2)
        from django.contrib.auth import models

        try:
            user = models.User.objects.get(username="admin")
            LOG.debug("Updating 'admin' user password...")
            user.set_password(password)
            user.save()
        except models.User.DoesNotExist:
            LOG.info("Creating initial 'admin' user...")
            models.User.objects.create_superuser("admin", "root@localhost", password)

    @classmethod
    def remove_system_artifacts(cls):
        """Bulk-remove all model instances that might have produced cruft on the system (outside mini-buildd's home)"""
        for chroot in util.models().Chroot.mbd_get_prepared():
            try:
                chroot.Admin.mbd_remove(chroot)
            except BaseException as e:
                LOG.warning(f"Failed to remove {chroot}: {e}")

    @classmethod
    def loaddata(cls, file_name):
        django.core.management.call_command("loaddata", file_name)

    @classmethod
    def dumpdata(cls, app_path):
        LOG.debug(f"Dumping data for: {app_path}")
        django.core.management.call_command("dumpdata", app_path, indent=2, format="json")
