from enum import Enum, auto
from subprocess import CalledProcessError, run

from pitop.common.command_runner import run_command
from pitop.common.logger import PTLogger


class NotificationAction:
    def __init__(self, call_to_action_text, command_str) -> None:
        self.call_to_action_text = call_to_action_text
        self.command_str = command_str


class NotificationActionManager:
    def __init__(self):
        self.actions = list()
        self.default_action = None
        self.close_action = None

    def add_action(self, call_to_action_text, command_str) -> None:
        action = NotificationAction(call_to_action_text, command_str)
        self.actions.append(action)

    def set_default_action(self, command_str) -> None:
        default_action = NotificationAction("", command_str)
        self.default_action = default_action

    def set_close_action(self, command_str) -> None:
        close_action = NotificationAction("", command_str)
        self.close_action = close_action


class NotificationUrgencyLevel(Enum):
    low = auto()
    normal = auto()
    critical = auto()


def send_notification(
    title: str,
    text: str,
    icon_name: str = "",
    timeout: int = 0,
    app_name: str = "",
    notification_id: int = -1,
    actions_manager: NotificationActionManager = None,
    urgency_level: NotificationUrgencyLevel = None,
    capture_notification_id: bool = True,
) -> str:

    # Check that `notify-send-ng` is available, as it's not a hard dependency of the package
    try:
        run(["dpkg-query", "-l", "notify-send-ng"], capture_output=True, check=True)
    except CalledProcessError:
        raise Exception("notify-send-ng not installed")

    cmd = "/usr/bin/notify-send "
    cmd += "--print-id "
    cmd += "--expire-time=" + str(timeout) + " "

    if icon_name:
        cmd += "--icon=" + icon_name + " "

    if notification_id >= 0:
        cmd += "--replace=" + str(notification_id) + " "

    if actions_manager is not None:
        for action in actions_manager.actions:
            cmd += (
                '--action="'
                + action.call_to_action_text
                + ":"
                + action.command_str
                + '" '
            )

        if actions_manager.default_action is not None:
            cmd += (
                "--default-action=" + actions_manager.default_action.command_str + " "
            )

        if actions_manager.close_action is not None:
            cmd += "--close-action=" + actions_manager.close_action.command_str + " "

    if app_name:
        cmd += "--app-name=" + app_name + " "

    if urgency_level is not None:
        cmd += "--urgency=" + urgency_level.name + " "

    cmd += ' "' + title + '" '
    cmd += '"' + text + '"'

    PTLogger.info("notify-send command: {}".format(cmd))

    try:
        resp_stdout = run_command(cmd, 2000, capture_output=capture_notification_id)
    except Exception as e:
        PTLogger.warning("Failed to show message: {}".format(e))
        raise
    return resp_stdout

[(34, 'enum.auto', 'auto', False, 'from enum import Enum, auto\n'), (35, 'enum.auto', 'auto', False, 'from enum import Enum, auto\n'), (36, 'enum.auto', 'auto', False, 'from enum import Enum, auto\n'), (53, 'subprocess.run', 'run', False, 'from subprocess import CalledProcessError, run\n'), (97, 'pitop.common.command_runner.run_command', 'run_command', False, 'from pitop.common.command_runner import run_command\n')]