# coding=utf-8

from __future__ import absolute_import, print_function, unicode_literals

from unittest import TestCase

from six import text_type

from abilian.core.entities import all_entity_classes
from abilian.core.models.subjects import Group, User

from ..models import Message, PrivateMessage


def check_editable(object):
    if hasattr(object, '__editable__'):
        for k in object.__editable__:
            assert hasattr(object, k)


def test_user():
    user = User(
        first_name="John",
        last_name="Test User",
        email="test@example.com",
        password="toto")
    check_editable(user)

    assert "John Test User" == user.name
    assert "John Test User" == text_type(user)
    # self.assertEquals(len(user.messages), 0)


def test_user_follow():
    # id is provided by DB (which is not used in this test), and is required for
    # having in (user1 != user2) == True
    user1 = User(
        id=1,
        first_name="John",
        last_name="Test User 1",
        email="test1@example.com",
        password="toto")
    user2 = User(
        id=2,
        first_name="Joe",
        last_name="Test User 2",
        email="test2@example.com",
        password="toto")

    assert len(user1.followers) == 0
    assert len(user1.followees) == 0
    assert len(user2.followers) == 0
    assert len(user2.followees) == 0

    user1.follow(user2)

    assert user1.is_following(user2)
    assert len(user2.followers) == 1
    assert len(user1.followees) == 1
    assert len(user2.followees) == 0
    assert len(user1.followers) == 0
    assert user2 in user1.followees

    user1.unfollow(user2)

    assert not user1.is_following(user2)
    assert len(user1.followers) == 0
    assert len(user1.followees) == 0
    assert len(user2.followers) == 0
    assert len(user2.followees) == 0
    assert user2 not in user1.followers


def test_group():
    user = User(
        first_name="John",
        last_name="Test User",
        email="test@example.com",
        password="toto")
    group = Group(name="Group 1")

    user.join(group)

    assert user.is_member_of(group)
    assert len(group.members) == 1
    assert len(user.groups) == 1
    assert group.members == {user}
    assert user.groups == {group}

    user.leave(group)

    assert not user.is_member_of(group)
    assert len(group.members) == 0
    assert len(user.groups) == 0


def test_private_message():
    pm = PrivateMessage(creator_id=0, recipient_id=0)
    check_editable(pm)


def test_status_update():
    user = User(
        first_name="John",
        last_name="Test User",
        email="test@example.com",
        password="toto")
    # self.assertEquals(len(user.messages), 0)

    message = Message()
    message.author = user
    check_editable(message)

    # self.assertEquals(len(user.messages), 1)
    # self.assertEquals(user.messages[0], message)
    # self.assertEquals(message.author_id, user.uid)


def test_tags():
    m = Message(content="abc #123 #cde #voilà_l_été #789")
    assert m.tags == ['123', 'cde', 'voilà_l_été', '789']


def test_get_all_entity_classes():
    classes = all_entity_classes()
    assert Message in classes
    assert PrivateMessage in classes
