from django.apps import (
    AppConfig,
    apps,
)
from django.utils.functional import Promise
from django.utils.translation import gettext_lazy

from okrand import get_conf


def get_args_from_proxy(proxy):
    args = getattr(proxy, '_args', None)
    if args is None:
        args = getattr(proxy, '_proxy____args', None)
    return args


def get_original_string_from_proxy(proxy):
    args = get_args_from_proxy(proxy)
    return args[0]


def upgrade_verbose_name(obj):
    original = obj.verbose_name
    if isinstance(original, Promise):
        obj.verbose_name._okrand_original_string = get_original_string_from_proxy(original)
        assert not isinstance(obj.verbose_name._okrand_original_string, Promise)
        return

    obj.verbose_name = gettext_lazy(original)
    obj.verbose_name._okrand_original_string = original
    assert not isinstance(obj.verbose_name._okrand_original_string, Promise)


def upgrade_plural(obj):
    original = obj.verbose_name_plural
    if isinstance(original, Promise):
        args = get_args_from_proxy(original)
        # if a Django autogenerated plural string
        if len(args) == 2 and args[0] == '{}s':
            original = str(original)
        else:
            assert len(args) == 1
            obj.verbose_name_plural._okrand_original_string = args[0]
            assert not isinstance(obj.verbose_name_plural._okrand_original_string, Promise)
            return

    new = gettext_lazy(original)
    obj.verbose_name_plural = new
    obj.verbose_name_plural._okrand_original_string = original
    assert not isinstance(obj.verbose_name_plural._okrand_original_string, Promise)


class OkrandConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'okrand'

    def ready(self):
        if get_conf('django_model_upgrade') in ('1', 'true'):
            for model in apps.get_models():
                upgrade_verbose_name(model._meta)
                upgrade_plural(model._meta)

                for field in model._meta._get_fields(reverse=False):
                    upgrade_verbose_name(field)
