"""This module contains the management methods for the ``common`` app"""

import operator

from django.apps import apps
from django.contrib.contenttypes.management import get_contenttypes_and_models
from django.db import DEFAULT_DB_ALIAS


def create_ordered_contenttypes(app_config):
    """Create the contenttypes for the given ``app_config``

    Parameters
    ----------
    app_config: django ``AppConfig``
        The config of the app for which we want to create the contenttypes

    For the other parameters, see the ``create_contenttypes`` django method.

    Notes
    -----
    The django method ``create_contenttypes`` is connected to the ``post_migrate`` signal.
    In our given context MASTER/SLAVE, the way of django doing have two flaws:

    1 - The ``post_migrate`` signal is called after the ``migrate`` command and it might lead
        to creation of the contenttypes "on the fly" during a data migration.
    2 - The django method don't order the models when inserting the contenttypes.

    This two flaws lead to one big one: The contenttypes between the SLAVES and the MASTER
    might vary, we might get a different contenttypes id for the same model.

    So we create our own custom method and call it manually when needed.

    See Also
    --------
    ``django.contrib.contenttypes.management.create_contenttypes``

    """

    ContentType = apps.get_model('contenttypes', 'ContentType')  # pylint: disable=invalid-name
    content_types, app_models = get_contenttypes_and_models(
        app_config,
        DEFAULT_DB_ALIAS,
        ContentType
    )

    # Order the app models by their names
    app_models = sorted(app_models.items(), key=operator.itemgetter(0))

    cts = [
        ContentType(
            app_label=app_config.label,
            model=model_name,
        )
        for (model_name, model) in app_models
        if model_name not in content_types
    ]
    ContentType.objects.using(DEFAULT_DB_ALIAS).bulk_create(cts)
