# standard
from datetime import datetime
from typing import Any


class PluginAssayColumn:
    """
    Abstract interface for assay column data read.

    Methods to be implemented:

    - :meth:`get_all_values`: returns all available values for assay column with type depending on the plugin used
    - :meth:`get_values_from_time`: returns available values for assay column with type depending on the plugin used from a time interval
    - :meth:`get_values_from_depth`: returns available values for assay column with type depending on the plugin used from a depth interval

    Args:
        hole_id: collar hole_id
        column_str: name of column
    """

    class InvalidInterface(Exception):
        pass

    def __init__(self, hole_id: str, column_str: str):
        self.hole_id = hole_id
        self.column_str = column_str

    def get_distinct_col_values(self, related_column: str = "") -> Any:
        """
        Returns distinct available value for assay column

        Args:
            related_column:  (str) related assay column (default ""). Used if an assay column is stored as row
        Returns:
            Any: assay column value
        """
        raise PluginAssayColumn.InvalidInterface()

    def get_all_values(
        self, remove_none: bool = False, related_column: str = ""
    ) -> Any:
        """
        Returns all values available for assay as numpy arrays

        Args:
            remove_none: (bool) remove none values (default False)
            related_column:  (str) related assay column (default ""). Used if an assay column is stored as row
        Returns:
            Any: assay value
        """
        raise PluginAssayColumn.InvalidInterface()

    def get_values_from_time(
        self,
        date_min: datetime,
        date_max: datetime,
        remove_none: bool = False,
        related_column: str = "",
    ) -> Any:
        """
        Returns available values for assay as numpy arrays from a time interval.

        Args:
            date_min (datetime): minimum datetime
            date_max (datetime): maximum datetime
            remove_none: (bool) remove none values (default False)
            related_column:  (str) related assay column (default ""). Used if an assay column is stored as row
        Returns:
            Any: assay value
        """
        raise PluginAssayColumn.InvalidInterface()

    def get_values_from_depth(
        self,
        depth_min: float,
        depth_max: float,
        remove_none: bool = False,
        related_column: str = "",
    ) -> Any:
        """
        Returns available values for assay as numpy arrays from a depth interval

        Args:
            depth_min (float): minimum depth
            depth_max (float): maximum depth
            remove_none (bool): remove none values (default False)
            related_column:  (str) related assay column (default ""). Used if an assay column is stored as row
        related_column: str = ""
        Returns:
            Any: assay value
        """
        raise PluginAssayColumn.InvalidInterface()
