from dataclasses import dataclass

from a2a.server.agent_execution import RequestContext

from a2a_acl.a2a_utils.send_message import extract_file_from_message
from a2a_acl.protocol_extension import A2A_ACL_PROTOCOL_URI
from a2a_acl.protocol_extension.primitives import (
    extract_performative,
    extract_codec,
    Performative,
)

# class Performative(StrEnum):
"""Performatives that are used in messages.
* TELL, ACHIEVE, ASK are basic performatives inspired by KQML.
* PROPOSE is suited for arbitration or consensus (from FIPA-ACL).
"""

TELL = Performative("inform")
ACHIEVE = Performative("request")
ASK = Performative("ask")
PROPOSE = Performative("propose")


@dataclass
class ACLMessage:
    performative: Performative
    content: str
    sender: str
    codec: str


@dataclass
class ACLIncomingMessage(ACLMessage):
    task_id: str
    origin: RequestContext
    attached_file: str | None = None


def acl_of_a2a(context: RequestContext) -> ACLIncomingMessage:
    if (context.configuration is None) or (
        context.configuration.push_notification_config is None
    ):
        sender = None
    else:
        sender = context.configuration.push_notification_config.url

    attached = extract_file_from_message(context.message)

    if (
        context.message.metadata is None
        or A2A_ACL_PROTOCOL_URI not in context.message.metadata
    ):
        error_message = "Incoming message not in ACL format (missing metadata)."
        print(error_message)
        raise Exception(error_message)
    else:
        i = extract_performative(context)
        c = extract_codec(context)
        content = context.get_user_input()

        return ACLIncomingMessage(
            i,
            content,
            sender,
            c,
            task_id=context.message.task_id,
            origin=context,
            attached_file=attached,
        )
