# Django REST Framework
from rest_framework import serializers

# Tower
from awx.api.fields import VerbatimField
from awx.api.serializers import BaseSerializer
from awx.conf.models import Setting
from awx.conf import settings_registry


class SettingSerializer(BaseSerializer):
    """Read-only serializer for activity stream."""

    value = VerbatimField(allow_null=True)

    class Meta:
        model = Setting
        fields = ('id', 'key', 'value')
        readonly_fields = ('id', 'key', 'value')

    def __init__(self, instance=None, data=serializers.empty, **kwargs):
        if instance is None and data is not serializers.empty and 'key' in data:
            try:
                instance = Setting.objects.get(key=data['key'])
            except Setting.DoesNotExist:
                pass
        super(SettingSerializer, self).__init__(instance, data, **kwargs)


class SettingCategorySerializer(serializers.Serializer):
    """Serialize setting category """

    url = serializers.CharField(
        read_only=True,
    )
    slug = serializers.CharField(
        read_only=True,
    )
    name = serializers.CharField(
        read_only=True,
    )


class SettingFieldMixin(object):
    """Mixin to use a registered setting field class for API display/validation."""

    def to_representation(self, obj):
        if getattr(self, 'encrypted', False) and isinstance(obj, basestring) and obj:
            return '$encrypted$'
        return obj

    def to_internal_value(self, value):
        if getattr(self, 'encrypted', False) and isinstance(value, basestring) and value.startswith('$encrypted$'):
            raise serializers.SkipField()
        obj = super(SettingFieldMixin, self).to_internal_value(value)
        return super(SettingFieldMixin, self).to_representation(obj)


class SettingSingletonSerializer(serializers.Serializer):
    """Present a group of settings (by category) as a single object."""

    def __init__(self, instance=None, data=serializers.empty, **kwargs):
        # Instance (if given) should be an object with attributes for all of the
        # settings in the category; never an actual Setting model instance.
        assert instance is None or not hasattr(instance, 'pk')
        super(SettingSingletonSerializer, self).__init__(instance, data, **kwargs)

    def get_fields(self):
        fields = super(SettingSingletonSerializer, self).get_fields()
        try:
            category_slug = self.context['view'].kwargs.get('category_slug', 'all')
        except (KeyError, AttributeError):
            category_slug = ''
        for key in settings_registry.get_registered_settings(category_slug=category_slug):
            if self.instance and not hasattr(self.instance, key):
                continue
            extra_kwargs = {}
            # Make LICENSE read-only here; update via /api/v1/config/ only.
            if key == 'LICENSE':
                extra_kwargs['read_only'] = True
            field = settings_registry.get_setting_field(key, mixin_class=SettingFieldMixin, for_user=bool(category_slug == 'user'), **extra_kwargs)
            fields[key] = field
        return fields
