from urllib.parse import urlencode


class BaseApi:
    """
    A base class to build paths and a baseline CRUD interface for an entity set.
    """

    def __init__(self, client):
        super().__init__()
        self._client = client

        if not self.endpoint:
            raise NotImplementedError('self.endpoint must be set when subclassing this class.')

    def _build_path(self, key=None, endpoint=None, property=None, queryparams=None, *args, **kwargs):
        """
        Build path to endpoint, including support for key lookup of a single entity.
        """
        endpoint = endpoint or self.endpoint

        if key:
            endpoint += f'/{key}'

        if property:
            endpoint += f'/{property}'

        if queryparams:
            endpoint += f'?{urlencode(queryparams)}'

        return endpoint

    def get(self, key, property=None, queryparams=None):
        """
        Get an entity. e.g. GET /path/to/endpoint/key
        """
        response_json, _ = self._client._get(self._build_path(key=key, property=property, queryparams=queryparams))
        return response_json

    def exists(self, key, queryparams=None):
        """
        Check if an entity exists.
        """
        from . import WidenError
        from requests.exceptions import RequestException

        try:
            _, status_code = self._client._get(self._build_path(key=key, queryparams=queryparams))
        except (WidenError, RequestException) as exception:
            return False
        else:
            return status_code == 200
