# -*- coding: utf-8 -*-
import logging
import hashlib
import urllib.parse

from django.conf import settings
from django.core.cache import cache

from requests.exceptions import RequestException
from events.common_app.utils import requests_session

logger = logging.getLogger(__name__)


class KinopoiskAPIClient(object):
    def __init__(self, api_url=settings.KINOPOISK_API_URL, backend_secret=settings.KINOPOISK_API_SECRET):
        self.api_url = api_url
        self.backend_secret = backend_secret

    def get_user_profile_data(self, uid, timeout=60, use_cache=True):
        url = urllib.parse.urljoin(self.api_url, 'users')
        params = {
            'xUid': self._get_xuid_param(uid),
        }
        response, cache_used = self._make_get_request(uid, url, params, timeout=timeout, use_cache=use_cache)
        logger.info(
            'uid=%s url=%s params=%s response=%s cache_used=%s',
            uid,
            url,
            params,
            response,
            cache_used,
        )
        return response

    def _get_xuid_param(self, uid):
        if not uid:
            raise ValueError('No uid param')
        return '%s:%s' % (uid, hashlib.md5(('%s%s' % (uid, self.backend_secret)).encode('utf-8')).hexdigest())

    def _make_get_request(self, uid, url, params, timeout=60, use_cache=True):
        response = None
        cache_used = True
        url = '%s?%s' % (url, urllib.parse.urlencode(params))
        if use_cache and 'xUid' in params:
            response = cache.get(self._get_response_cache_key(uid, url))
        if not response:
            cache_used = False
            response = self._make_real_request(uid, url, timeout=timeout)
        return response, cache_used

    def _get_response_cache_key(self, uid, url):
        user_key_part = hashlib.sha256(url).hexdigest()
        return 'kinopoisk_api_client:%s_%s' % (uid, user_key_part)

    def _make_real_request(self, uid, url, timeout=60):
        try:
            response = requests_session.get(url, timeout=settings.DEFAULT_TIMEOUT)
            response_code = response.status_code
            response_content = response.json()
        except RequestException as err:
            response_code = err.response.status_code
            response_content = {'error': err.response.text}
        else:
            self._set_response_to_cache_if_needed(uid, url, response, response_content)
        logger.info(
            'uid=%s url=%s response_status=%s response=%s type=real',
            uid,
            url,
            response_code,
            response_content,
        )
        return response_content

    def _set_response_to_cache_if_needed(self, uid, url, response, response_content):
        # todo: test me
        if response.status_code == 200:
            cache.set(self._get_response_cache_key(uid, url), response_content, 10)
