import requests
import json
from urlparse import urljoin
from requests.exceptions import RequestException
from django.conf import settings

from core.exceptions import CoreException


TANKER_URL = settings.TANKER_URL
TANKER_TOKEN = settings.TANKER_TOKEN


class APIError(CoreException):
    pass


class Keyset(object):

    def __init__(self, name, keys=None):
        self.name = name
        self.keys = keys or {}

    def add_key(self, key):
        self.keys[key.name] = key

    def get_key(self, key_name):
        return self.keys.get(key_name, None)

    def to_dict(self):
        keyset = {
            self.name: {
                'keys': {name: k.to_dict() for name, k in self.keys.iteritems()},
            }
        }
        return keyset


class Key(object):

    def __init__(self, name, context='', translations=None):
        self.name = name
        self.context = context
        self.translations = translations or {}

    def add_translation(self, language, form):
        self.translations.update(
            {language: {'form': form}}
        )

    def set_context(self, context):
        self.context = context

    def to_dict(self):
        key = {
            'info': {
                'context': self.context,
            },
            'translations': self.translations,
        }
        return key


class Tanker(object):
    def __init__(self, project_id, branch_id='master',
                 url=TANKER_URL, token=TANKER_TOKEN):
        self.project_id = project_id
        self.branch_id = branch_id
        self.base_url = url
        self.token = token

    def _get_request_data(self, keyset_id):
        data = dict()
        data['project-id'] = self.project_id
        data['branch-id'] = self.branch_id
        data['keyset-id'] = keyset_id
        return data

    def _get_headers(self):
        headers = dict()
        headers['AUTHORIZATION'] = self.token
        headers['Expect'] = ''
        return headers

    def _keyset_operation(self, url, keyset, language):
        keysets = dict(keysets=keyset.to_dict())
        # keysets = {
        #     keyset_name_ie_dev_pages: {
        #         keys: {
        #             page.name: page_name,
        #             page.text: page_text,
        #         }
        #     }
        # }

        translation_json = json.dumps(keysets)
        files = {'file': ('translation', translation_json)}
        headers = self._get_headers()
        data = self._get_request_data(keyset.name)
        data['language'] = language
        data['format'] = 'tjson'
        try:
            r = requests.post(url, files=files, data=data, headers=headers)
        except RequestException:
            raise APIError
        if r.status_code != 200:
            raise APIError(r.text)

    def merge_keyset(self, keyset, language):
        url = urljoin(self.base_url, '/keysets/merge/')
        return self._keyset_operation(url, keyset, language)

    def append_keyset(self, keyset, language):
        url = urljoin(self.base_url, '/keysets/onlyadd/')
        return self._keyset_operation(url, keyset, language)

    def create_keyset(self, keyset, language):
        url = urljoin(self.base_url, '/keysets/create/')
        return self._keyset_operation(url, keyset, language)

    def replace_keyset(self, keyset, language):
        url = urljoin(self.base_url, '/keysets/replace/')
        return self._keyset_operation(url, keyset, language)

    def download_keyset(self, keyset_id):
        url = urljoin(self.base_url, '/keysets/json/')
        params = self._get_request_data(keyset_id)
        try:
            return requests.get(url, params=params).json()
        except RequestException:
            raise APIError

    def list_keysets(self):
        resource = '/admin/project/{0}/keysets/'.format(self.project_id)
        headers = self._get_headers()
        url = urljoin(self.base_url, resource)
        try:
            data = requests.get(url, headers=headers).json()
        except RequestException as e:
            raise APIError(repr(e))
        return [v['name'] for v in data['data']['items']]
