from django.test import TestCase
from mongoengine import ValidationError as me_ValidationError
from mongoengine import Document, fields
from rest_framework import serializers

from rest_framework_mongoengine.serializers import DocumentSerializer


# How "id" works in mongoengine
# -----------------------------
#
# In mongoengine models "id" field works as follows:
# If there's a field with primart_key=True, id refers to that field.
# Otherwise, mongoengine automatically creates an
# id = ObjectIdField(primary_key=True, db_ref="_id") on Document.
# See mongoengine's: base/metaclasses.py:TopLevelDocumentMetaclass.
#
# There's a way to shoot yourself in the leg with this behavior of id:
# you can define a field, named "id", on your mongoengine Document, but
# not set primary_key=True on it. In that case mongoengine will create a field
# "_id" in the database and a model field, named id, that will refer to that
# database field, but also will create a database field "id" that can't be
# accessed from mongoengine side. I believe, this is a bug of mongoengine.
#
# Don't do this, kids!

class CustomIdModel(Document):
    id = fields.StringField(primary_key=True)


class CustomIdSerializer(DocumentSerializer):
    id = serializers.CharField()

    class Meta:
        model = CustomIdModel
        fields = '__all__'


class IncorrectSerializer(DocumentSerializer):
    """This serializer doesn't override id field, thus it is incorrect."""
    class Meta:
        model = CustomIdModel
        fields = '__all__'


class IncorrectSerializerTestCase(TestCase):
    data = {
        "id": "foo"
    }

    def doCleanups(self):
        CustomIdModel.drop_collection()

    def test_incorrect(self):
        """This test shows that if we've overridden id field on a model and
        haven't explicitly specified an id field on serializer, like in
        IncorrectSerializer, the serializer successfully passes DRFME
        validation, but Mongoengine validation raises a ValidationError
        with a puzzling error message.

        We need a more explicit error message here, which tells DRFME user to
        override id field on serializer; don't know, how to implement this.
        """
        serializer = IncorrectSerializer(data=self.data)
        assert serializer.is_valid()
        with self.assertRaises(me_ValidationError):
            serializer.save()
#        #print "serializer.fields = %s" % serializer.fields
#        #print "serializer.validated_data = %s" % serializer.validated_data
#        #serializer.save()
#
#    def test_readable(self):
#        serializer = IncorrectSerializer()


class CustomIdTestCase(TestCase):
    data = {
        "id": "foo"
    }

    def doCleanups(self):
        CustomIdModel.drop_collection()

    def test_get(self):
        pass