from abc import ABC, abstractmethod
import zmq
from typing import List
import threading

from mininet.models.models import Address


class Node(ABC):
    def __init__(self):
        self.context = zmq.Context.instance()
        self.socket: zmq.Socket | List[zmq.Socket] | None = None
        self._thread = threading.Thread(target=self.run)
        self._stop = threading.Event()

    @abstractmethod
    def init_socket(self, addr: Address | List[Address]):
        """Initializes all sockets used by the subclass."""

    @abstractmethod
    def run(self):
        """Runs blocking operations of the subclass."""

    def start(self):
        self._stop.clear()
        self._thread.start()

    def stop(self):
        self._stop.set()

    def is_stopped(self):
        return self._stop.is_set()

    def destroy(self):
        self.context.destroy()
