"""
Protocolos de comunicación para diferentes tipos de medidores.

Este módulo define las clases de protocolo para procesar mensajes de diferentes tipos de medidores.
Cada protocolo debe implementar la interfaz MeterProtocol.

Desarrolladores:
- Para añadir un nuevo protocolo, cree una nueva clase que herede de MeterProtocol
- Implemente el método process_message() para el nuevo protocolo
- Actualice el diccionario de protocolos en la clase MeterConnection en meter_connection.py
"""

from abc import ABC, abstractmethod
import re
from datetime import datetime

class MeterProtocol(ABC):
    """Clase base abstracta para protocolos de medidores."""

    @abstractmethod
    def process_message(self, message):
        """
        Procesa un mensaje recibido del medidor.
        
        Args:
            message (str): El mensaje raw recibido del medidor.
        
        Returns:
            dict: Un diccionario con los datos procesados del medidor.
        """
        pass

class IEC62056Protocol(MeterProtocol):
    """Implementación del protocolo IEC62056 para medidores."""

    def process_message(self, message):
        """
        Procesa un mensaje en formato IEC62056.
        
        Args:
            message (str): Mensaje recibido del medidor.
        
        Returns:
            dict: Datos procesados del medidor.
        """
        reception_time = datetime.now().isoformat()
        
        if message.startswith("EV IM:"):
            return self.process_ev_im_message(message, reception_time)
        else:
            return self.process_standard_message(message, reception_time)

    def process_ev_im_message(self, message, reception_time):
        """Procesa mensajes que comienzan con 'EV IM:'."""
        lines = message.strip().split('\n')
        ev_im_line = lines[0]
        obis_data = '|'.join(line.strip() for line in lines)

        ev_im_match = re.match(r'EV IM:([0-9A-F:]+)', ev_im_line)
        ev_im = ev_im_match.group(1) if ev_im_match else ""

        return {
            "fecha": reception_time,
            "EV IM": ev_im,
            "OBIS": obis_data
        }

    def process_standard_message(self, message, reception_time):
        """Procesa mensajes estándar que no comienzan con 'EV IM:'."""
        lines = message.strip().split('\n')
        obis_data = '|'.join(line.strip() for line in lines)

        return {
            "fecha": reception_time,
            "EV IM": "",
            "OBIS": obis_data
        }