from __future__ import annotations

from dataclasses import dataclass
from typing import List

from .addressing import Addressing
from .uds import ServiceId, NegativeResponseCode


@dataclass
class Message:
    addressing: Addressing
    bytes: List[int]
    payload_protocol: str = "unknown"
    timeout: float | None = None

    @property
    def id(self) -> int:
        return self.addressing.id

    @property
    def reply(self) -> int:
        return self.addressing.reply

    def with_reply_id(self, reply_id: int) -> "Message":
        if self.addressing.mode == "unicast":
            addressing = Addressing.unicast(
                identifier=self.addressing.id,
                reply=reply_id,
                request_extension=self.addressing.request_extension,
                reply_extension=self.addressing.reply_extension,
            )
        else:
            addressing = Addressing.unicast(
                identifier=self.addressing.id,
                reply=reply_id,
                request_extension=self.addressing.request_extension,
                reply_extension=self.addressing.reply_extension,
            )
        return Message(addressing=addressing, bytes=self.bytes, payload_protocol=self.payload_protocol)

    def response(self, response_bytes: List[int]) -> "Message":
        response_addressing = Addressing.id_only(self.addressing.reply, extension=self.addressing.reply_extension)
        return Message(addressing=response_addressing, bytes=response_bytes, payload_protocol=self.payload_protocol)

    def response_pending(self) -> "Message":
        if not self.bytes:
            return self
        response = [ServiceId.negative_response_code, self.bytes[0], int(NegativeResponseCode.request_correctly_received_response_pending)]
        return self.response(response)

    def negative_response(self, nrc: NegativeResponseCode) -> "Message":
        if not self.bytes:
            return self
        response = [ServiceId.negative_response_code, self.bytes[0], int(nrc)]
        return self.response(response)
