# SPDX-FileCopyrightText: 2024 Luca Weiss
# SPDX-License-Identifier: GPL-3.0-only

import datetime
import threading
from typing import Callable
from . import esim


class NotificationTask:
    """
    Schedule processing of notifications
    """
    thread: threading.Thread = threading.Thread(target=None)

    def __init__(self, available_slots: list[int], esim_manager: esim.ESimManager):
        self.available_slots = available_slots
        self.esim_manager = esim_manager

    def start(self, success_cb: Callable[[], None], error_cb: Callable[[esim.ESimError, list[str]], None]) -> None:
        """
        Start the task if it's not already running.
        """
        if self.thread.is_alive():
            print("INFO: Ignoring NotificationTask start request, already running!")
            return

        self.thread = threading.Thread(target=self.notification_thread, args=(success_cb, error_cb))
        self.thread.daemon = True
        self.thread.start()

    def _format_log(self, time: datetime.timedelta, content: str) -> str:
        return f"[{time.seconds}.{int(time.microseconds/10000):02}s] {content}"

    def notification_thread(self, success_cb: Callable[[], None], error_cb: Callable[[esim.ESimError, list[str]], None]) -> None:
        start_time = datetime.datetime.now()
        logs = []
        success = True
        try:
            for slot in self.available_slots:
                notifications = self.esim_manager.get_notifications(slot)
                print(f"Notification slot {slot}:")
                for notification in notifications:
                    print(notification)
                    notification_success = False
                    for val in notification.process(remove=True):
                        if isinstance(val, esim.LpacBackend.LpacProgress):
                            msg = self._format_log(datetime.datetime.now() - start_time, f"{val.message} - {val.data}")
                            print(msg)
                            logs.append(msg)
                        elif isinstance(val, esim.LpacBackend.LpacData):
                            msg = self._format_log(datetime.datetime.now() - start_time, f"{val.message} - {val.data}")
                            print(msg)
                            logs.append(msg)
                            if val.message == "success":
                                notification_success = True
                        elif isinstance(val, esim.LpacBackend.LpacMisc):
                            msg = self._format_log(datetime.datetime.now() - start_time, f"{val.value}")
                            print(msg)
                            logs.append(msg)
                        else:
                            raise esim.ESimError(f"Unhandled value type {type(val)} - {val}")

                    if not notification_success:
                        msg = f"Didn't get success item for notification {notification}"
                        print(msg)
                        logs.append(msg)
                        success = False

            if success:
                success_cb()
            else:
                error_cb(esim.ESimError("One of more notifications failed to process!"), logs)

        except esim.ESimError as e:
            print(f"ESim process exception: {e}")
            error_cb(e, logs)
