import time

from BigStash import __version__
from .conf import BigStashAPISettings
from requests import Session
from requests.sessions import merge_setting
from requests.structures import CaseInsensitiveDict


DEFAULT_HEADERS = CaseInsensitiveDict({
    'User-agent': 'BigStash Python SDK v{}'.format(__version__),
    'Accept': 'application/vnd.deepfreeze+json',
    'Content-Type': 'application/vnd.deepfreeze+json'
})


class BigStashAPIBase(object):
    def __init__(self, auth=None, settings=None, headers=None,
                 *args, **kwargs):
        """
        Initialize the Base API client functions
        :param auth: optional authentication tuple or object for request
        :param settings: optional :class:`BigStashAPISettings` instance to use.
        :param headers: optional dict  of HTTP Headers
        """
        self.settings = settings or BigStashAPISettings()
        if 'base_url' not in self.settings:
            raise TypeError("Must provide base_url setting")
        self._base_url = self.settings['base_url'].rstrip('/')

        self._headers = DEFAULT_HEADERS
        if headers is not None:
            self._headers = merge_setting(
                headers, self._headers,
                dict_class=CaseInsensitiveDict)

        self._auth = None
        if 'auth' is not None:
            self._auth = auth

        # setup requests session
        self._session = self._setup_session()

        super(BigStashAPIBase, self).__init__(*args, **kwargs)

    def _setup_session(self):
        s = Session()
        if 'verify' in self.settings:  # default is True
            s.verify = self.settings['verify']
        if 'trust_env' in self.settings:
            s.trust_env = self.settings['trust_env']
        if self._auth is not None:
            s.auth = self._auth

        s.headers = merge_setting(  # add our headers to requests' default set
            self._headers, s.headers, dict_class=CaseInsensitiveDict)

        return s

    def api_url(self, path=''):
        """
        Return a full URL to the API resource at 'path'
        API URLs always end in '/'.
        """
        return "/".join([self._base_url, path.rstrip('/'), ''])

    def add_date(self, headers):
        if 'date' not in [h.lower() for h in headers]:
            headers['Date'] = time.strftime('%a, %d %b %Y %H:%M:%S GMT',
                                            time.gmtime(time.time()))

    def get(self, path, *args, **kwargs):
        """Sends a GET request, returns result. Assumes a JSON response.

        :param url: URL to GET
        :param \*\*kwargs: Optional arguments that ``requests.get`` takes.
        """
        self.add_date(kwargs.setdefault('headers', {}))
        return self._session.get(self.api_url(path), *args, **kwargs)

    def post(self, path, *args, **kwargs):
        """Sends a POST request, returns result.

        :param url: URL to GET
        :param \*\*kwargs: Optional arguments that ``requests.get`` takes.
        """
        self.add_date(kwargs.setdefault('headers', {}))
        return self._session.post(self.api_url(path), *args, **kwargs)

@@ -2544,35 +2544,36 @@
 %0A        :param 
-url
+path
 : URL to GET%0A   
@@ -2891,19 +2891,366 @@
  :param 
-url
+path: URL to POST%0A        :param %5C*%5C*kwargs: Optional arguments that %60%60requests.post%60%60 takes.%0A        %22%22%22%0A        self.add_date(kwargs.setdefault('headers', %7B%7D))%0A        return self._session.post(self.api_url(path), *args, **kwargs)%0A%0A    def patch(self, path, *args, **kwargs):%0A        %22%22%22 Sends a PATCH request, returns results.%0A%0A        :param path
 : URL to
@@ -3242,35 +3242,37 @@
 am path: URL to 
-GET
+PATCH
 %0A        :param 
@@ -3310,35 +3310,37 @@
 that %60%60requests.
-get
+patch
 %60%60 takes.%0A      
@@ -3423,35 +3423,390 @@
  self._session.p
-ost
+atch(self.api_url(path), *args, **kwargs)%0A%0A    def delete(self, path, *args, **kwargs):%0A        %22%22%22 Sends a DELETE request, returns results.%0A%0A        :param path: URL to DELETE%0A        :param %5C*%5C*kwargs: Optional arguments that %60%60requests.delete%60%60 takes.%0A        %22%22%22%0A        self.add_date(kwargs.setdefault('headers', %7B%7D))%0A        return self._session.delete
 (self.api_url(pa

Add patch() and delete() methods in BigStashAPIBase class