from .hdsocv2 import DACControllerHDSoCv2


class DACControllerCodlir(DACControllerHDSoCv2):
    def __init__(self, board):
        """Codlir DAC controller.

        Codlir uses Daisy Chained SPI DAC chips AD5674 in two chains
        Due to this configuration the DAC controller works a bit different.
        However the API should be the same as all other DAC controllers.

        Args:
            board: the board object must contain the SPI daisy chains.
        """
        self.board = board

    def _bus_amount_check_or_raise(self):
        if not len(self.spi) >= 1:
            raise AttributeError(
                f"SPI connection should have one bus for the DACs got {len(self.spi)}"
            )

    def _bus_length_check_or_raise(self):
        if len(self.spi[0b00]) != 4:
            raise AttributeError("Bus 0 should have four devices")

    def _get_device_num(self, channel):
        """Return (device_id, bus_id) for a channel.

        This function will compute the correct bus and device number.
        The devices are connected on the Codlir eval board in the following way:
        - 0-15: DAC 0
        - 16-31: DAC 1
        - 32-47: DAC 3
        - 48-63: DAC 2

        Args:
            channel: The channel number.

        Returns:
            Tuple of (device_id, bus_id)

        Raises:
        TypeError: If the channel is not an int.
            ValueError: If the channel is not in the range of 0-63.
        """
        self.validate_channel_or_raise(self.board, channel)
        for spi_bus in self.spi:
            for spi_dev in spi_bus:
                if channel in spi_dev.channelmap.keys():
                    return (spi_dev.bus_id, spi_dev.device_id)
        raise ValueError(f"Channel {channel} not found in SPI connection")
