import json
import logging
import requests
import os

CA_BUNDLE = os.path.join(os.path.dirname(__file__),
                         '../../../../misc/certs/ca-bundle.crt')


def is_csrf_token_expired(token):
    from datetime import datetime
    expiry = token.split('##')[0]
    if expiry <= datetime.now().strftime('%Y%m%d%H%M%S'):
        return True
    return False


class API(object):
    """A class that knows how to make requests to a Balrog server, including
       pre-retrieving CSRF tokens and data versions.

       url_template: The URL to submit to when request() is called. Standard
                     Python string interpolation can be used here in
                     combination with url_template_vars.
       prerequest_url_template: Before submitting the real request, a HEAD
                                operation will be done on this URL. If the
                                HEAD request succeeds, it is expected that
                                there will be X-CSRF-Token and X-Data-Version
                                headers in the response. If the HEAD request
                                results in a 404, another HEAD request to
                                /csrf_token will be made in attempt to get a
                                CSRF Token. This URL can use string
                                interpolation the same way url_template can.
                                In some cases this may be the same as the
                                url_template.
    """
    verify = False
    auth = None
    url_template = None
    prerequest_url_template = None
    url_template_vars = None

    def __init__(self, api_root='https://aus4-admin-dev.allizom.org/api',
                 auth=None, ca_certs=CA_BUNDLE, timeout=60,
                 raise_exceptions=True):
        """ Creates an API object which wraps REST API of Balrog server.

        api_root: API root URL of balrog server
        auth    : a tuple of (username, password) or None
        ca_certs: CA bundle. It follows python-requests `verify' usage.
                  If set to False, no SSL verification is done.
                  If set to True, it tries to load a CA bundle from certifi
                  module.
                  If set to string, puthon-requests uses it as a pth to path to
                  CA bundle.
        timeout : request timeout
        raise_exceptions: controls exception handling of python-requests.
        """
        self.api_root = api_root.rstrip('/')
        self.verify = ca_certs
        assert isinstance(auth, tuple) or auth == None, \
            "auth should be set to tuple or None"
        self.auth = auth
        self.timeout = timeout
        self.raise_exceptions = raise_exceptions
        self.session = requests.session()
        self.csrf_token = None

    def request(self, data=None, method='GET'):
        url = self.api_root + self.url_template % self.url_template_vars
        prerequest_url = self.api_root + \
            self.prerequest_url_template % self.url_template_vars
        # If we'll be modifying things, do a GET first to get a CSRF token
        # and possibly a data_version.
        if method != 'GET' and method != 'HEAD':
            # Use the URL of the resource we're going to modify first,
            # because we'll need a CSRF token, and maybe its data version.
            try:
                res = self.do_request(prerequest_url, None, 'HEAD')
                # If a data_version was specified we shouldn't overwrite it
                # because the caller may be acting on a modified version of
                # a specific older version of the data.
                if 'data_version' not in data:
                    data['data_version'] = res.headers['X-Data-Version']
                # We may already have a non-expired CSRF token, but it's
                # faster/easier just to set it again even if we do, since
                # we've already made the request.
                data['csrf_token'] = self.csrf_token = res.headers[
                    'X-CSRF-Token']
            except requests.HTTPError, e:
                # However, if the resource doesn't exist yet we may as well
                # not bother doing another request solely for a token unless
                # we don't have a valid one already.
                if e.response.status_code != 404:
                    raise
                if not self.csrf_token or is_csrf_token_expired(self.csrf_token):
                    res = self.do_request(
                        self.api_root + '/csrf_token', None, 'HEAD')
                    data['csrf_token'] = self.csrf_token = res.headers[
                        'X-CSRF-Token']

        return self.do_request(url, data, method)

    def do_request(self, url, data, method):
        logging.debug('Balrog request to %s' % url)
        if data is not None and 'csrf_token' in data:
            sanitised_data = data.copy()
            del sanitised_data['csrf_token']
            logging.debug('Data sent: %s' % sanitised_data)
        else:
            logging.debug('Data sent: %s' % data)
        headers = {'Accept-Encoding': 'application/json',
                   'Accept': 'application/json'}
        try:
            req = self.session.request(
                method=method, url=url, data=data, timeout=self.timeout,
                verify=self.verify, auth=self.auth, headers=headers)
            if self.raise_exceptions:
                req.raise_for_status()
            return req
        except requests.HTTPError, e:
            logging.error('Caught HTTPError: %s' % e.response.content)
            raise

    def get_data(self):
        resp = self.request()
        return (json.loads(resp.content), resp.headers['X-Data-Version'])


class Release(API):
    url_template = '/releases/%(name)s'
    prerequest_url_template = '/releases/%(name)s'

    def __init__(self, name, **kwargs):
        super(Release, self).__init__(**kwargs)
        self.name = name
        self.url_template_vars = dict(name=name)


    def update_release(self, version, product, hashFunction, releaseData,
                       data_version=None, schemaVersion=None):
        data = dict(name=self.name, version=version, product=product,
                    hashFunction=hashFunction, data=releaseData)
        if data_version:
            data['data_version'] = data_version
        if schemaVersion:
            data['schema_version'] = schemaVersion
        return self.request(method='POST', data=data)


class SingleLocale(API):
    url_template = '/releases/%(name)s/builds/%(build_target)s/%(locale)s'
    prerequest_url_template = '/releases/%(name)s'

    def __init__(self, name, build_target, locale, **kwargs):
        super(SingleLocale, self).__init__(**kwargs)
        self.name = name
        self.build_target = build_target
        self.locale = locale
        self.url_template_vars = dict(name=name, build_target=build_target,
                                      locale=locale)
        # keep a copy to be used in get_data()
        self.release_kwargs = kwargs

    def get_data(self):
        data, data_version = {}, None
        # If the locale-specific API end point returns 404, we have to use the
        # top level blob to get the data version. Because this requires 2 not
        # atomic HTTP requests, we start with the top level blob and use its
        # data version.
        top_level = Release(name=self.name, **self.release_kwargs)
        # Use data version from the top level blob
        try:
            _, data_version = top_level.get_data()
        except requests.HTTPError, e:
            if e.response.status_code == 404:
                # top level blob doesn't exist, assume there is no data
                return data, data_version
            else:
                raise
        # Got data version. Try to get data from the locale specific blob.
        # Using data version from the top level blob prevents possible race
        # conditions if another client updates the locale blob between the
        # first request and the call below.
        try:
            data, _ = super(SingleLocale, self).get_data()
            return data, data_version
        except requests.HTTPError, e:
            if e.response.status_code == 404:
                # locale blob doesn't exist, no data
                return data, data_version
            else:
                raise

    def update_build(self, product, version, hashFunction, buildData,
                     alias=None, schemaVersion=None, data_version=None):
        data = dict(product=product, version=version,
                    data=buildData, hashFunction=hashFunction)
        if alias:
            data['alias'] = alias
        if data_version:
            data['data_version'] = data_version
        if schemaVersion:
            data['schema_version'] = schemaVersion

        return self.request(method='PUT', data=data)


class Rule(API):
    url_template = '/rules/%(rule_id)s'
    prerequest_url_template = '/rules/%(rule_id)s'

    def __init__(self, rule_id, **kwargs):
        super(Rule, self).__init__(**kwargs)
        self.rule_id = rule_id
        self.url_template_vars=dict(rule_id=rule_id)

    def update_rule(self, **rule_data):
        return self.request(method='POST', data=rule_data)
