from __future__ import annotations

import gaarf
import pytest

from googleads_housekeeper.adapters import notifications


class TestNotifications:

    @pytest.fixture
    def empty_payload(self):
        return notifications.MessagePayload(
            task_id='450c7bc6-5fe1-402c-9c23-53f1818903e1',
            task_name='test_task',
            task_formula='GOOGLE_ADS_INFO:impressions > 10',
            placements_excluded_sample=None,
            total_placement_excluded=0,
            recipient='test_recipient')

    @pytest.mark.parametrize(
        'notification_type, notification_class',
        [('slack', notifications.SlackNotifications),
         ('email', notifications.GoogleCloudAppEngineEmailNotifications),
         ('console', notifications.ConsoleNotifications),
         ('unknown', notifications.NullNotifications)])
    def test_create_notification_service_creates_correct_notification_class(
            self, notification_type, notification_class):
        notification_service = notifications.NotificationFactory(
        ).create_nofication_service(notification_type=notification_type)
        assert isinstance(notification_service, notification_class)

    def test_sendnotification_raises_error_for_unknown_notification_type(
            self, empty_payload):
        notification_service = notifications.NullNotifications(
            notification_type='unknown')
        with pytest.raises(ValueError):
            notification_service.send(empty_payload)


class TestGoogleCloudAppEngineEmailNotifications:

    def test_prepare_message_returns_correct_message_elements_for_empty_payload(
            self):
        empty_payload = notifications.MessagePayload(
            task_id='450c7bc6-5fe1-402c-9c23-53f1818903e1',
            task_name='test_task',
            task_formula='GOOGLE_ADS_INFO:impressions > 10',
            placements_excluded_sample=None,
            total_placement_excluded=0,
            recipient='test_recipient')
        sender = notifications.GoogleCloudAppEngineEmailNotifications(
            project_id='fake-project')
        message = sender._prepare_message(empty_payload)
        assert message.body == ''
        assert message.to == ['test_recipient']
        assert message.subject == 'No placements were excluded'
        assert message.sender == (
            'Placements_Excluder___test_task@fake-project.appspotmail.com')

    def test_prepare_message_returns_correct_message_elements_for_non_empty_payload(
            self):
        excluded_placements = gaarf.report.GaarfReport(
            results=[[
                'test-placement',
                'example.com',
                'GOOGLE_ADS_INFO:impressions > 10',
            ]],
            column_names=['name', 'placement', 'reason'])
        payload_with_placements = notifications.MessagePayload(
            task_id='450c7bc6-5fe1-402c-9c23-53f1818903e1',
            task_name='test_task',
            task_formula='GOOGLE_ADS_INFO:impressions > 10',
            placements_excluded_sample=excluded_placements,
            total_placement_excluded=1,
            recipient='test_recipient')
        sender = notifications.GoogleCloudAppEngineEmailNotifications(
            project_id='fake-project')
        message = sender._prepare_message(payload_with_placements)
        assert message.to == ['test_recipient']
        assert message.subject == '1 placements were excluded'
        assert message.sender == (
            'Placements_Excluder___test_task@fake-project.appspotmail.com')
        assert 'test-placement' in message.html
        assert 'example.com' in message.html
