from typing import List

from xplordb.datamodel.collar import Collar
from xplordb.datamodel.dataset import Dataset
from xplordb.datamodel.lith import Lith
from xplordb.datamodel.metadata import RawCollarMetadata
from xplordb.datamodel.person import Person
from xplordb.datamodel.survey import Survey


class WriteInterface:
    """
    Interface to write data into OpenLogConnection (person, dataset, collar, survey and lith)

    Check for import availability :

    - :meth:`can_import_collar`

    Import data:

    - :meth:`import_collar`
    - :meth:`import_datasets`
    - :meth:`import_persons`
    - :meth:`import_surveys`
    - :meth:`import_liths`

    By default, all functions are not implemented and raises :class:`InvalidInterface` exception.

    """

    class InvalidInterface(Exception):
        pass

    class ImportException(Exception):
        pass

    def can_import_collar(self) -> bool:
        """
        Indicate if connection can import collar

        Returns:
            bool: by default, return False, must be implemented in WriteInterface implementation

        """
        return False

    def import_collar(self, collars: List[Collar], import_policy: dict) -> None:
        """
        Import collar into OpenLogConnection interface.

        Args:
            collars: collars to be imported
            import_policy : conflicts handling
        """
        pass

    def import_collar_metadata(
        self, metadatas: List[RawCollarMetadata], import_policy: dict
    ) -> None:
        """
        Import collar metadata into OpenLogConnection interface.

        Args:
            metadatas: metadatas to be imported
            import_policy : conflicts handling
        """
        pass

    def import_datasets(self, datasets: List[Dataset]) -> None:
        """
        Import dataset into OpenLogConnection interface.

        Args:
            datasets: datasets to be imported
        """
        raise WriteInterface.InvalidInterface()

    def person_code_max_size(self) -> int:
        """
        Define maximum size for person code creation

        Returns:
            int : 0, must be implemented in interface
        """
        return 0

    def import_persons(self, persons: List[Person]) -> None:
        """
        Import persons into OpenLogConnection interface.

        raises :class:`InvalidInterface` if not implemented

        Args:
            persons: persons to be imported
        """
        raise WriteInterface.InvalidInterface()

    def import_surveys(self, surveys: List[Survey], import_policy: dict) -> None:
        """
        Import survey into OpenLogConnection interface.

        raises :class:`InvalidInterface` if not implemented

        Args:
            surveys: surveys to be imported
        """
        raise WriteInterface.InvalidInterface()

    def selected_collar_survey_definition_available(self) -> bool:
        """
        Return True if the collar survey definition is available
        :return: A boolean value.
        """
        return False

    def selected_collar_edition_available(self) -> bool:
        """
        Return True if the collar edition is available
        :return: A boolean value.
        """

        return False

    def replace_collar_surveys(self, hole_id: str, surveys: List[Survey]):
        """
        Replace survey for collar

        raises :class:`InvalidInterface` if not implemented

        Args:
            hole_id:: The collar id of the hole
            surveys: new survey for collar
        """
        raise WriteInterface.InvalidInterface()

    def replace_collar_planned_surveys(self, hole_id: str, survey: Survey):
        """
        c

        raises :class:`InvalidInterface` if not implemented

        Args:
            hole_id:: The collar id of the hole
            surveys: new survey for collar
        """
        raise WriteInterface.InvalidInterface()

    def update_collars(self, collar_list: List[Collar]) -> None:
        """
        Update collars from database.
        Args:
            - collar_list : list of collars to update
        """
        raise WriteInterface.InvalidInterface()

    def remove_collars(self, collar_ids: List[str]) -> bool:
        """
        Remove collars from database.
        Args:
            - collar_list : list of collars to remove
        Returns True if succeeded.
        """
        return False
