import requests
import threading
import queue

class Pulse:
    _endpoint = 'https://api-pulse.704app.com.br/logs'
    _valid_types = ['error', 'warn', 'info', 'debug', 'critical']

    def __init__(self, app: str, group_id: str):
        if not app or not group_id:
            raise Exception("Nome do app ou GroupID não fornecidos ao pulse.")

        self.app = app
        self.group_id = group_id
        self._log_queue = queue.Queue()
        self._stop_event = threading.Event()
        self._worker_thread = threading.Thread(target=self._worker, daemon=True, name="pulse_worker")
        self._worker_thread.start()

    def _worker(self):
        while not self._stop_event.is_set():
            try:
                payload = self._log_queue.get(timeout=3)
                try:
                    requests.post(self._endpoint, json=payload, timeout=5)
                except Exception as e:
                    pass
                finally:
                    self._log_queue.task_done()
            except queue.Empty:
                continue

    def _send_log(self, log_type: str, message: str, context: str):
        # para debug no pulse, remover o not
        if log_type not in self._valid_types:
            return

        payload = {
            'type': log_type,
            'message': message,
            'app': self.app,
            'context': context,
            'groupId': self.group_id
        }

        self._log_queue.put(payload)

    def error(self, message: str, context: str): self._send_log('error', message, context)
    def warn(self, message: str, context: str): self._send_log('warn', message, context)
    def info(self, message: str, context: str): self._send_log('info', message, context)
    def debug(self, message: str, context: str): self._send_log('debug', message, context)
    def critical(self, message: str, context: str): self._send_log('critical', message, context)
    def emergence(self, message: str, context: str): self._send_log('emergence', message, context)

    def close(self):
        self._stop_event.set()
        self._worker_thread.join(timeout=2)
