# coding=utf-8
from typing import cast

import requests

from ..Monitors.monitor import Monitor
from ..util import format_datetime
from .alerter import Alerter, AlertType, register


@register
class PushoverAlerter(Alerter):
    """Send push notification via Pushover."""

    _type = "pushover"

    def __init__(self, config_options: dict) -> None:
        super().__init__(config_options)

        self.pushover_token = cast(
            str, self.get_config_option("token", required=True, allow_empty=False)
        )
        self.pushover_user = cast(
            str, self.get_config_option("user", required=True, allow_empty=False)
        )

        self.support_catchup = True

    def send_pushover_notification(self, subject: str, body: str) -> None:
        """Send a push notification."""

        requests.post(
            "https://api.pushover.net/1/messages.json",
            data={
                "token": self.pushover_token,
                "user": self.pushover_user,
                "title": subject,
                "message": body,
            },
        )

    def send_alert(self, name: str, monitor: Monitor) -> None:
        """Build up the content for the push notification."""

        alert_type = self.should_alert(monitor)
        downtime = monitor.get_downtime()

        if monitor.is_remote():
            host = " on %s " % monitor.running_on
        else:
            host = " on host %s" % self.hostname

        subject = ""
        body = ""

        if alert_type == AlertType.NONE:
            return
        elif alert_type == AlertType.FAILURE:
            subject = "[%s] Monitor %s Failed!" % (self.hostname, name)
            body = """Monitor %s%s has failed.\n
            Failed at: %s
            Downtime: %s
            Virtual failure count: %d
            Additional info: %s
            Description: %s""" % (
                name,
                host,
                format_datetime(monitor.first_failure_time()),
                downtime,
                monitor.virtual_fail_count(),
                monitor.get_result(),
                monitor.describe(),
            )
            try:
                if monitor.recover_info != "":
                    body += "\nRecovery info: %s" % monitor.recover_info
            except AttributeError:
                body += "\nNo recovery info available"

        elif alert_type == AlertType.SUCCESS:
            subject = "[%s] Monitor %s succeeded" % (self.hostname, name)
            body = (
                "Monitor %s%s is back up.\nOriginally failed at: %s\nDowntime: %s\nDescription: %s"
                % (
                    name,
                    host,
                    format_datetime(monitor.first_failure_time()),
                    downtime,
                    monitor.describe(),
                )
            )

        elif alert_type == AlertType.CATCHUP:
            subject = "[%s] Monitor %s failed earlier!" % (self.hostname, name)
            body = (
                "Monitor %s%s failed earlier while this alerter was out of hours.\nFailed at: %s\nVirtual failure count: %d\nAdditional info: %s\nDescription: %s"
                % (
                    name,
                    host,
                    format_datetime(monitor.first_failure_time()),
                    monitor.virtual_fail_count(),
                    monitor.get_result(),
                    monitor.describe(),
                )
            )

        else:
            self.alerter_logger.error("Unknown alert type %s", alert_type)
            return

        if not self._dry_run:
            try:
                self.send_pushover_notification(subject, body)
            except Exception:
                self.alerter_logger.exception("Couldn't send push notification")
                self.available = False
        else:
            self.alerter_logger.info("dry_run: would send push notification: %s", body)

@@ -93,43 +93,8 @@
 tor%0A
-from ..util import format_datetime%0A
 from
@@ -118,16 +118,29 @@
 Alerter,
+ AlertLength,
  AlertTy
@@ -1233,1245 +1233,161 @@
 or)%0A
-        downtime = monitor.get_downtime()%0A%0A        if monitor.is_remote():%0A            host = %22 on %25s %22 %25 monitor.running_on%0A        else:%0A            host = %22 on host %25s%22 %25 self.hostname%0A%0A        subject = %22%22%0A        body = %22%22%0A%0A        if alert_type == AlertType.NONE:%0A            return%0A        elif alert_type == AlertType.FAILURE:%0A            subject = %22%5B%25s%5D Monitor %25s Failed!%22 %25 (self.hostname, name)%0A            body = %22%22%22Monitor %25s%25s has failed.%5Cn%0A            Failed at: %25s%0A            Downtime: %25s%0A            Virtual failure count: %25d%0A            Additional info: %25s%0A            Description: %25s%22%22%22 %25 (%0A                name,%0A                host,%0A                format_datetime(monitor.first_failure_time()),%0A                downtime,%0A                monitor.virtual_fail_count(),%0A                monitor.get_result(),%0A                monitor.describe(),%0A            )%0A            try:%0A                if monitor.recover_info != %22%22:%0A                    body += %22%5CnRecovery info: %25s%22 %25 monitor.recover_info%0A            except AttributeError:%0A                body += %22%5CnNo recovery info available%22%0A%0A        elif alert_type == AlertType.SUCCESS:%0A            subject = %22%5B%25s%5D Monitor %25s succeeded%22 %25 (self.hostname, name)%0A  
+%0A        if alert_type == AlertType.NONE:%0A            return%0A        subject = self.build_message(AlertLength.NOTIFICATION, alert_type, monitor)%0A
         
   bo
@@ -1386,1082 +1386,72 @@
     
-  
 body = 
-(%0A                %22Monitor %25s%25s is back up.%5CnOriginally failed at: %25s%5CnDowntime: %25s%5CnDescription: %25s%22%0A                %25 (%0A                    name,%0A                    host,%0A                    format_datetime(monitor.first_failure_time()),%0A                    downtime,%0A                    monitor.describe(),%0A                )%0A            )%0A%0A        elif alert_type == AlertType.CATCHUP:%0A            subject = %22%5B%25s%5D Monitor %25s failed earlier!%22 %25 (self.hostname, name)%0A            body = (%0A                %22Monitor %25s%25s failed earlier while this alerter was out of hours.%5CnFailed at: %25s%5CnVirtual failure count: %25d%5CnAdditional info: %25s%5CnDescription: %25s%22%0A                %25 (%0A                    name,%0A                    host,%0A                    format_datetime(monitor.first_failure_time()),%0A                    monitor.virtual_fail_count(),%0A                    monitor.get_result(),%0A                    monitor.describe(),%0A                )%0A            )%0A%0A        else:%0A            self.alerter_logger.error(%22Unknown alert type %25s%22, alert_type)%0A            return
+self.build_message(AlertLength.FULL, alert_type, monitor)
 %0A%0A  

Update pushover alerter to build_message