from __future__ import annotations

from typing import Tuple, Type

from ._alphabet import BaseAlphabet
from ._cdata import CData
from ._ffi import ffi, lib

__all__ = ["BaseLprob"]


class BaseLprob:
    """
    Base log-probabilities.

    Parameters
    ----------
    nmm_base_lprob
        Base log-probabilities.
    alphabet
        Four-nucleotides alphabet.
    """

    def __init__(self, nmm_base_lprob: CData, alphabet: BaseAlphabet):
        self._nmm_base_lprob = nmm_base_lprob
        if self._nmm_base_lprob == ffi.NULL:
            raise RuntimeError("`nmm_base_lprob` is NULL.")
        self._alphabet = alphabet

    @classmethod
    def create(
        cls: Type[BaseLprob],
        alphabet: BaseAlphabet,
        lprobs: Tuple[float, float, float, float],
    ) -> BaseLprob:
        """
        Create base log-probabilities.

        Parameters
        ----------
        alphabet
            Four-nucleotides alphabet.
        lprobs
            Log probability of each nucleotide.
        """
        nmm_base_lprob = lib.nmm_base_lprob_create(alphabet.nmm_base_abc, *lprobs)
        return cls(nmm_base_lprob, alphabet)

    @property
    def alphabet(self) -> BaseAlphabet:
        return self._alphabet

    @property
    def nmm_base_lprob(self) -> CData:
        return self._nmm_base_lprob

    def lprob(self, nucleotide: bytes) -> float:
        return lib.nmm_base_lprob_get(self._nmm_base_lprob, nucleotide)

    def __del__(self):
        if self._nmm_base_lprob != ffi.NULL:
            lib.nmm_base_lprob_destroy(self._nmm_base_lprob)
