"""
Classes to serialize the RESTful representation of Drycc API models.
"""
import logging

from django.contrib.admin.models import LogEntry
from django.contrib.auth import get_user_model
from oauth2_provider.models import Grant, AccessToken
from rest_framework import serializers

from api.models import Message, MessagePreference
from api.utils import timestamp2datetime

User = get_user_model()
logger = logging.getLogger(__name__)


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'first_name', 'last_name',
                  'is_staff', 'is_active', 'is_superuser')
        read_only_fields = ('id', 'username', 'is_staff', 'is_active',
                            'is_superuser')


class UserEmailSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'email')


class ListSerializer(serializers.Serializer):
    section = serializers.CharField(max_length=500, required=False)

    @staticmethod
    def validate_section(section):
        field = section.split(',') if section else None
        if field is None:
            return None
        return [timestamp2datetime(float(field[0])),
                timestamp2datetime(float(field[1]))]


class UserGrantsSerializer(serializers.ModelSerializer):
    """Serialize user status for a Grant model."""

    class Meta:
        model = Grant
        fields = '__all__'
        read_only_fields = ['id', 'user', 'code', 'application', 'expires',
                            'redirect_uri', 'scope', 'created', 'updated',
                            'code_challenge', 'code_challenge_method', 'nonce',
                            'claims']


class UserTokensSerializer(serializers.ModelSerializer):
    """Serialize user status for a AccessToken model."""
    application = serializers.ReadOnlyField(source='application.name')
    token_checksum = serializers.ReadOnlyField(required=False)

    class Meta:
        model = AccessToken
        fields = '__all__'
        read_only_fields = ['id', 'user', 'source_refresh_token', 'token',
                            'id_token', 'application', 'expires', 'scope',
                            'created', 'updated']


class UserLogsSerializer(serializers.ModelSerializer):
    """Serialize user status for a AccessToken model."""

    class Meta:
        model = LogEntry
        fields = '__all__'
        read_only_fields = ['action_time', 'user', 'content_type', 'object_id',
                            'object_repr', 'action_flag', 'change_message']


class MessageSerializer(serializers.ModelSerializer):
    """Serialize message model."""
    date = serializers.DateTimeField(
        source='created_at', format='%b %d, %Y, %H:%M', read_only=True
    )

    class Meta:
        model = Message
        fields = ['id', 'category', 'title', 'content', 'full_content',
                  'severity', 'is_read', 'action_link', 'action_text', 'date']
        read_only_fields = ['id', 'date']


class MessagePreferenceSerializer(serializers.ModelSerializer):
    """Serialize message preference model."""

    class Meta:
        model = MessagePreference
        fields = ['email_alerts', 'push_alerts', 'webhook_url',
                  'notify_security', 'notify_system', 'notify_product',
                  'notify_alert', 'notify_service']


class ServiceMessageSerializer(MessageSerializer):
    username = serializers.CharField(write_only=True)

    class Meta(MessageSerializer.Meta):
        fields = MessageSerializer.Meta.fields + ['username']

    def create(self, validated_data):
        from django.contrib.auth import get_user_model
        User = get_user_model()
        username = validated_data.pop('username')
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            raise serializers.ValidationError({"username": "User not found."})
        validated_data['user'] = user
        return super().create(validated_data)
