# standard libraries
import os
import collections.abc
import collections
#import http.cookies
# third party libraries
pass
# first party libraries
pass


__where__ = os.path.dirname(os.path.abspath(__file__))


class RequestCookies(collections.abc.Mapping):
    
    def __init__(self, **cookies):
        self._cookies = cookies
    
    @classmethod
    def from_header(cls, header):
        #parsed_cookies = http.cookies.SimpleCookie()
        #parsed_cookies.load(header)
        #cookies = {key: value.value for key, value in parsed_cookies.items()}
        cookies = {}
        for cookie in header.split(';'):
            cookie = cookie.strip(' ')
            morsels = cookie.split('=')
            if len(morsels) == 0:
                continue
            elif len(morsels) == 1:
                key = morsels[0]
                value = None
            else:
                key = morsels[0].strip()
                value = '='.join(morsels[1:])
            key = key.strip()
            if value is not None:
                value = value.strip()
            cookies[key] = value
        return cls(**cookies)
    
    def __getitem__(self, key):
        return self._cookies[key]
    
    def __iter__(self):
        return iter(self._cookies)
    
    def __len__(self):
        return len(self._cookies)
    
    def __str__(self):
        return '; '.join(
            '{}={}'.format(
                key, http.cookies._quote(value)
            ) for key, value in self.items()
        )
    
    def __repr__(self):
        return '{}.{}({})'.format(
            self.__module__, self.__class__.__name__, ', '.join(
                "{}='{}'".format(key, value) for key, value in self.items()
            )
        )


class ResponseCookie:
    
    def __init__(self, key, value='', max_age=None, expires=None, path=None,
                 domain=None, secure=False, http_only=False):
        self.key = key
        self.value = value
        self.max_age = max_age
        self.expires = expires
        self.path = path
        self.domain = domain
        self.secure = secure
        self.http_only = http_only
    
    def __repr__(self):
        return '{}.{}({})'.format(
            self.__module__, self.__class__.__name__, ', '.join(
                '{}={}'.format(name, repr(getattr(self, name))) for name in (
                    'key', 'value', 'max_age', 'expires', 'path', 'domain', 
                    'secure', 'http_only',
                )
            )
        )
    
    def __str__(self):
        key = self.key
        if self.value is not None:
            value = self.value
        else:
            value = ''
        cookie_segments = ['{}={}'.format(key, value), ]
        if self.max_age is not None:
            cookie_segments.append('Max-Age={}'.format(self.max_age))
        if self.expires is not None:
            cookie_segments.append(
                'Expires={:%a, %d-%b-%Y %T GMT}'.format(self.expires)
            )
        if self.path is not None:
            cookie_segments.append('Path={}'.format(self.path))
        if self.domain is not None:
            cookie_segments.append('Domain={}'.format(self.domain))
        if self.secure:
            cookie_segments.append('Secure')
        if self.http_only:
            cookie_segments.append('HttpOnly')
        return '; '.join(cookie_segments)


class ResponseCookies(collections.abc.MutableMapping):
    
    def __init__(self, *cookies):
        self._cookies = collections.OrderedDict(
            (cookie.key, cookie) for cookie in cookies
        )
    
    def set(self, key, value='', max_age=None, expires=None, path=None, 
            domain=None, secure=False, http_only=False):
        self[key] = ResponseCookie(
            key, value, max_age, expires, path, domain, secure, http_only
        )
    
    def set_from_header(self, cookie):
        raise NotImplementedError
    
    def __getitem__(self, key):
        return self._cookies[key]
    
    def __delitem__(self, key):
        del self._cookies[key]
    
    def __iter__(self):
        return iter(self._cookies)
    
    def __len__(self):
        return len(self._cookies)
    
    def __setitem__(self, key, value):
        if isinstance(value, ResponseCookie):
            self._cookies[key] = value
        else:
            self.set(key, value)
    
    def __str__(self):
        return '\n'.join(
            '{}: {}'.format(key, value) for key, value in self.headers
        )
    
    def __repr__(self):
        return '{}.{}({})'.format(
            self.__module__, self.__class__.__name__, ', '.join(
                (repr(cookie) for cookie in self.values())
            )
        )
