# -*- coding: utf-8 -*-

# Copyright (C) 2019 Google Inc.
# Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>

"""Test people mentions notifications."""

import datetime
import unittest

import ddt
import mock

from ggrc import settings
from ggrc.notifications import people_mentions


@ddt.ddt
class TestSendMentions(unittest.TestCase):
  """Test people mentions notifications."""

  @ddt.data(
      u"какой-то комментарий",
      u"Some comment",
  )
  def test_generate_mention_email(self, comment_text):
    """Test email generation."""
    comments_data = set()
    comments_data.add(
        people_mentions.CommentData(
            author="<EMAIL>",
            created_at=datetime.datetime(2017, 07, 10, 7, 31, 42),
            comment_text=comment_text,
        )
    )
    # pylint: disable=protected-access
    title, body = people_mentions._generate_mention_email(
        object_name="Object1",
        comments_data=comments_data,
    )
    expected_title = (u"<EMAIL> mentioned you "
                      u"on a comment within Object1")
    expected_body = (
        u"<EMAIL> mentioned you on a comment within Object1 "
        u"at 07/10/2017 00:31:42 PDT:\n" + comment_text + "\n"
    )
    self.assertEquals(title, expected_title)
    self.assertEquals(body, [expected_body])

  def test_find_mentions_one_per_user(self):
    """Test finding of people mentions."""
    comment_text = (
        u"<a href=\"mailto:<EMAIL>\"></a>"
        u"<a href=\"mailto:<EMAIL>\"></a>"
        u"<a href=\"mailto:<EMAIL>\"></a>"
    )
    comment = people_mentions.CommentData(
        author="<EMAIL>",
        created_at=datetime.datetime(2017, 1, 10, 7, 31, 42),
        comment_text=comment_text,
    )
    with mock.patch("ggrc.utils.user_generator.find_user", return_value=True):
      # pylint: disable=protected-access
      email_mentions = people_mentions._find_email_mentions([comment])
    self.assertEquals(len(email_mentions), 2)
    self.assertTrue(u"<EMAIL>" in email_mentions)
    self.assertTrue(u"<EMAIL>" in email_mentions)
    self.assertEquals(len(email_mentions[u"<EMAIL>"]), 1)
    self.assertEquals(len(email_mentions[u"<EMAIL>"]), 1)

    first_email_elem = next(iter(email_mentions[u"<EMAIL>"]))
    self.assertEquals(first_email_elem, comment)

    second_email_elem = next(iter(email_mentions[u"<EMAIL>"]))
    self.assertEquals(second_email_elem, comment)

  def test_find_mentions_in_comments(self):
    """Test find people mentions in several comments."""
    comment_text = (
        u"<a href=\"mailto:<EMAIL>\">one</a>"
        u"<a href=\"mailto:<EMAIL>\">two</a>"
        u"<a href=\"mailto:<EMAIL>\">three</a>"
    )
    first_comment = people_mentions.CommentData(
        author="<EMAIL>",
        created_at=datetime.datetime(2017, 1, 10, 7, 31, 42),
        comment_text=comment_text,
    )
    second_comment = people_mentions.CommentData(
        author="<EMAIL>",
        created_at=datetime.datetime(2017, 1, 10, 7, 31, 42),
        comment_text=comment_text,
    )
    with mock.patch("ggrc.utils.user_generator.find_user", return_value=True):
      # pylint: disable=protected-access
      email_mentions = people_mentions._find_email_mentions([first_comment,
                                                             second_comment])
    self.assertEquals(len(email_mentions), 2)
    self.assertEquals(len(email_mentions[u"<EMAIL>"]), 2)
    self.assertEquals(len(email_mentions[u"<EMAIL>"]), 2)

  def test_find_email_mentions_regex(self):
    """Test email regex in find mention function."""
    comment_text = (
        u"<a href=\"mail:{<EMAIL>}\"></a>"
        u"<a href=\"mailto:{<EMAIL>}\"></a>"
        u"<a url=\"mailto{<EMAIL>}\"></a>"
        u"<a href=\"mailto:{<EMAIL>}\"></a>"
    )
    comment = people_mentions.CommentData(
        author="<EMAIL>",
        created_at=datetime.datetime(2018, 1, 10, 7, 31, 42),
        comment_text=comment_text,
    )
    with mock.patch("ggrc.utils.user_generator.find_user", return_value=True):
      # pylint: disable=protected-access
      email_mentions = people_mentions._find_email_mentions([comment])
    self.assertEquals(len(email_mentions), 0)

  def test_find_email_mentions_mult(self):
    """Test finding several mentions in comments."""
    first_comment = people_mentions.CommentData(
        author="<EMAIL>",
        created_at=datetime.datetime(2018, 1, 10, 7, 31, 42),
        comment_text=u"One <a href=\"mailto:<EMAIL>\"></a>",
    )
    second_comment = people_mentions.CommentData(
        author="<EMAIL>",
        created_at=datetime.datetime(2018, 1, 10, 7, 31, 50),
        comment_text=u"Two <a href=\"mailto:<EMAIL>\"></a>",
    )
    comments = [first_comment, second_comment]
    with mock.patch("ggrc.utils.user_generator.find_user", return_value=True):
      # pylint: disable=protected-access
      email_mentions = people_mentions._find_email_mentions(comments)
    self.assertEquals(len(email_mentions), 1)
    self.assertTrue(u"<EMAIL>" in email_mentions)
    self.assertEquals(len(email_mentions[u"<EMAIL>"]), 2)
    related_comments = sorted(list(email_mentions[u"<EMAIL>"]))
    comments = sorted(comments)
    self.assertEquals(related_comments[0], comments[0])
    self.assertEquals(related_comments[1], comments[1])

  @mock.patch("ggrc.notifications.common.send_email")
  # pylint: disable=no-self-use
  def test_send_mentions(self, send_email_mock):
    """Test sending mentions emails."""
    comments_data = set()
    comments_data.add(
        people_mentions.CommentData(
            author="<EMAIL>",
            created_at=datetime.datetime(2018, 1, 10, 7, 31, 42),
            comment_text=u"One <a href=\"mailto:<EMAIL>\"></a>",
        )
    )
    comments_data.add(
        people_mentions.CommentData(
            author="<EMAIL>",
            created_at=datetime.datetime(2018, 1, 10, 7, 31, 50),
            comment_text=u"Two <a href=\"mailto:<EMAIL>\"></a>",
        )
    )
    with mock.patch("ggrc.utils.user_generator.find_user", return_value=True):
      people_mentions.send_mentions(
          object_name="Object",
          href="api/objects/1",
          comments_data=comments_data
      )
    expected_title = (u"<EMAIL> mentioned you "
                      u"on a comment within Object")
    body = settings.EMAIL_MENTIONED_PERSON.render(person_mention={
        "comments": [
            (u"<EMAIL> mentioned you on a comment within Object "
             u"at 01/09/2018 23:31:42 PST:\n"
             u"One <a href=\"mailto:<EMAIL>\"></a>\n"),
            (u"<EMAIL> mentioned you on a comment within Object "
             u"at 01/09/2018 23:31:50 PST:\n"
             u"Two <a href=\"mailto:<EMAIL>\"></a>\n"),
        ],
        "url": "api/objects/1",
    })
    send_email_mock.assert_called_once_with(u"<EMAIL>",
                                            expected_title, body)
