"""
By django convention this module is used to register models for the admin site.

See: https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.autodiscover
"""
import django.contrib

from mini_buildd.models import gnupg
from mini_buildd.models import source
from mini_buildd.models import distribution
from mini_buildd.models import repository
from mini_buildd.models import chroot
from mini_buildd.models import daemon
from mini_buildd.models import subscription

MODELS = [
    gnupg.AptKey,
    gnupg.Uploader,
    gnupg.Remote,
    source.Archive,
    source.Architecture,
    source.Component,
    source.Source,
    source.PrioritySource,
    repository.EmailAddress,
    distribution.Suite,
    distribution.Layout,
    distribution.Distribution,
    repository.Repository,
    chroot.Chroot,
    chroot.DirChroot,
    chroot.FileChroot,
    chroot.LVMChroot,
    chroot.LoopLVMChroot,
    chroot.BtrfsSnapshotChroot,
    daemon.Daemon,
    subscription.Subscription]


class AdminSite(django.contrib.admin.sites.AdminSite):
    index_template = "admin/mini_buildd.html"

    __APP_DATA = {
        "mini_buildd": {"order": 1, "setup": "setup"},
        "auth": {"order": 2},
    }
    __MODEL_DATA = {
        # Daemon
        "Daemon": {"class_path": "daemon.Daemon",
                   "header": "Daemon",
                   "order": 0},
        # Sources
        "Archive": {"class_path": "source.Archive",
                    "header": "Sources",
                    "order": 10},
        "Source": {"class_path": "source.Source",
                   "order": 11},
        "PrioritySource": {"class_path": "source.PrioritySource",
                           "order": 12},
        "AptKey": {"class_path": "gnupg.AptKey",
                   "order": 13},
        # Repositories
        "Layout": {"class_path": "distribution.Layout",
                   "header": "Repositories",
                   "order": 20},
        "Distribution": {"class_path": "distribution.Distribution",
                         "order": 21},
        "Repository": {"class_path": "repository.Repository",
                       "order": 22},
        "Uploader": {"class_path": "gnupg.Uploader",
                     "order": 23},
        # Chroots
        "DirChroot": {"class_path": "chroot.DirChroot",
                      "header": "Chroots",
                      "order": 30},
        "FileChroot": {"class_path": "chroot.FileChroot",
                       "order": 31},
        "LVMChroot": {"class_path": "chroot.LVMChroot",
                      "order": 32},
        "LoopLVMChroot": {"class_path": "chroot.LoopLVMChroot",
                          "order": 33},
        "BtrfsSnapshotChroot": {"class_path": "chroot.BtrfsSnapshotChroot",
                                "order": 34},
        # Remotes
        "Remote": {"class_path": "gnupg.Remote",
                   "header": "Remotes",
                   "order": 40},
        # Others
        "Architecture": {"class_path": "source.Architecture",
                         "header": "Others",
                         "order": 50},
        "Component": {"class_path": "source.Component",
                      "order": 51},
        "EmailAddress": {"class_path": "repository.EmailAddress",
                         "order": 52},
        "Suite": {"class_path": "distribution.Suite",
                  "order": 53},
        "Subscription": {"class_path": "subscription.Subscription",
                         "order": 54},
        "Chroot": {"class_path": "chroot.Chroot",
                   "order": 55},
    }

    def __init__(self):
        super().__init__("mini-buildd-admin")
        # Default action 'delete_selected' action does not call
        # custom delete.
        #
        # See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/
        #
        # So we just disable this default action. You can still delete
        # single objects from the model's form.
        self.disable_action("delete_selected")

        for m in MODELS:
            admin_class = getattr(m, "Admin")
            # We need the model class in ModelAdmin classmethods (i.e., in mbd_pca_all)
            admin_class.mbd_model = m
            self.register(m, admin_class)
            self._registry.update(django.contrib.admin.site._registry)  # Add other apps that have been autodiscovered

    def get_app_list(self, request):
        """Proper order && group header for mini_buildd app; others apps still sorted alphabetically."""
        app_dict = self._build_app_dict(request)
        app_list = sorted(app_dict.values(), key=lambda app: self.__APP_DATA[app["app_label"]].get("order", 999))
        for app in app_list:
            if app["app_label"] == "mini_buildd":
                app["models"].sort(key=lambda model: self.__MODEL_DATA[model["object_name"]].get("order", 999))
                app["mbd"] = self.__APP_DATA["mini_buildd"]

                for model in app["models"]:
                    model["mbd"] = self.__MODEL_DATA[model["object_name"]]
            else:
                app['models'].sort(key=lambda model: model['name'])

        return app_list


site = AdminSite()
