# -*- coding: utf-8 -*-
from __future__ import absolute_import

import six

from pypump.models.place import Place
from tests import PyPumpTest


class PersonTest(PyPumpTest):
    def setUp(self):
        super(PersonTest, self).setUp()
        self.response.data = {
            "id": "acct:TestUser@example.com",
            "preferredUsername": "TestUser",
            "url": "http://example.com/TestUser",
            "displayName": "Test Userson",
            "links": {
                "self": {
                    "href": "http://example.com/api/user/TestUser/profile",
                },
                "activity-inbox": {
                    "href": "http://example.com/api/user/TestUser/inbox",
                },
                "activity-outbox": {
                    "href": "http://example.com/api/user/TestUser/feed",
                },
            },
            "objectType": "person",
            "followers": {
                "url": "http://example.com/api/user/TestUser/followers",
                "totalItems": 72,
            },
            "following": {
                "url": "http://example.com/api/user/TestUser/following",
                "totalItems": 27,
            },
            "favorites": {
                "url": "http://example.com/api/user/TestUser/favorites",
                "totalItems": 720,
            },
            "location": {
                "objectType": "place",
                "displayName": "Home Tree, Pandora",
            },
            "summary": "I am a PyPump Test user, I am used for testing!",
            "image": {
                "url": "http://example.com/uploads/TestUser/some_image.jpg",
                "width": 96,
                "height": 96,
            },
            "pump_io": {
                "shared": False,
                "followed": False,
            },
            "updated": "2013-08-13T10:26:54Z",
            "liked": False,
            "shares": {
                "url": "http://example.com/api/person/BlahBlah/shares",
                "items": [],
            }
        }

    def test_person(self):
        person = self.pump.Person("TestUser@example.com")
        # is a Person object
        self.assertTrue(isinstance(person, type(self.pump.Person())))
        # repr
        self.assertEqual(person.__repr__(), '<Person: TestUser@example.com>')
        # string
        self.assertEqual(person.__str__(), self.response['displayName'])
        # unicode
        person.display_name = u'Test användarson'
        if six.PY3:
            self.assertEqual(person.__str__(), person.display_name)
        else:
            self.assertEqual(person.__str__(), person.display_name.encode('utf-8'))

    def test_follow(self):
        """ Tests that pypump sends correct data when attempting to follow a person """
        person = self.pump.Person("TestUser@example.com")

        # PyPump now expects the object returned back to it
        self.response.data = {
            "actor": {"objectType": "person", "id": "acct:foo@bar"},
            "verb": "follow",
            "object": self.response.data
        }
        person.follow()

        # Test verb is 'follow'
        self.assertEquals(self.request["verb"], "follow")

        # Test ID is the correct ID
        self.assertEquals(person.id, self.request["object"]["id"])

        # Ensure object type is correct
        self.assertEquals(person.object_type, self.request["object"]["objectType"])

    def test_update(self):
        """ Test that a update works """
        person = self.pump.Person("TestUser@example.com")
        person.summary = "New summary!"
        person.display_name = "New user"

        self.response.data = {
            "verb": "update",
            "actor": {"objectType": "person", "id": person.id},
            "object": {
                "id": person.id,
                "summary": person.summary,
                "displayName": person.display_name,
                "objectType": "person",
            },
        }

        person.update()

        self.assertEqual(self.request["verb"], "update")
        self.assertEqual(self.request["object"]["id"], person.id)
        self.assertEqual(self.request["object"]["objectType"], person.object_type)
        self.assertEqual(self.request["object"]["summary"], person.summary)
        self.assertEqual(self.request["object"]["displayName"], person.display_name)

    def test_unfollow(self):
        """ Test that you can unfollow a person """
        person = self.pump.Person("TestUser@example.com")

        self.response.data = {
            "actor": {"objectType": "person", "id": "acct:foo@bar"},
            "verb": "stop-following",
            "object": self.response.data
        }
        person.unfollow()

        self.assertEquals(self.request["verb"], "stop-following")
        self.assertEquals(self.request["object"]["id"], person.id)
        self.assertEquals(self.request["object"]["objectType"], person.object_type)

    def test_minimal_unserialize(self):
        """ Test the smallest amount of data can be given to unserialize """
        self.response.data = {
            "id": "acct:TestUser@example.com",
            "objectType": "person",
        }

        person = self.pump.Person("TestUser@example.com")

        self.assertEquals(self.response["id"], person.id)
        self.assertEquals(self.response["objectType"], person.object_type)

    def test_unserialize(self):
        """ Tests person unserialization is successful """
        # Make the person object
        person = self.pump.Person("TestUser@example.com")

        # Test unserialization is correct
        self.assertEqual(person.id, self.response["id"])
        self.assertEqual(person.username, self.response["preferredUsername"])
        self.assertEqual(person.display_name, self.response["displayName"])
        self.assertEqual(person.url, self.response["url"])
        self.assertEqual(person.summary, self.response["summary"])

        # Test image model was made
        #self.assertTrue(isinstance(person.image, self.pump.Image))

        # Test place model was made
        self.assertTrue(isinstance(person.location, Place))
