# coding: utf-8
from __future__ import unicode_literals

import requests
from memoize import memoize
from requests.exceptions import RequestException
from django.conf import settings
import re

import logging
log = logging.getLogger(__name__)


class Inflector(object):

    def __init__(self):
        self.url = 'http://{host}:{port}/wizard'.format(
            host=settings.INFLECTOR_HOST,
            port=settings.INFLECTOR_PORT,
        )

    def _make_request(self, request):
        params = dict(
            action='inflector',
            wizclient='fb',
            text=request,
        )
        try:
            r = requests.get(self.url, params=params, timeout=1)
        except RequestException as e:
            log.critical("Inflector error: %s", e.message)
            return {}
        if r.status_code != 200:
            log.critical("Inflector returned error page")
            return {}
        try:
            forms = r.json()
            return forms
        except ValueError as e:
            log.critical("Error in parsing response to json: %s", e.message)
        return {}

    @staticmethod
    def _parse_response(response):
        cases = ['nom', 'gen', 'dat', 'acc', 'ins', 'abl']
        full_name_cases = {}
        first_name_cases = {}
        last_name_cases = {}
        inflator_output_parser = re.compile('persn{(.+)}famn{(.+)}gender{.}')
        for i, case in enumerate(cases):
            try:
                m = inflator_output_parser.match(response['Form'][i]['Text'])
            except KeyError:
                m = False
                log.critical("Not valid json: %s", response)
            if m:
                full_name = m.groups()
                full_name_cases[case] = ' '.join(full_name)
                first_name_cases[case] = full_name[0]
                last_name_cases[case] = full_name[1]
        return first_name_cases, last_name_cases, full_name_cases

    @memoize(60)
    def get_cases(self, person):
        request = 'persn{%s}famn{%s}gender{%s};fio=1' % (
            person.first_name_ru,
            person.last_name_ru,
            'f' if person.gender else 'm',
        )
        response = self._make_request(request)
        return self._parse_response(response)

    def get_first_name_cases(self, person):
        return self.get_cases(person)[0]

    def get_last_name_cases(self, person):
        return self.get_cases(person)[1]

    def get_full_name_cases(self, person):
        return self.get_cases(person)[2]

    def set_cases_for_person(self, person):
        cases = self.get_cases(person)
        person._first_name_cases = cases[0]
        person._last_name_cases = cases[1]

    def __repr__(self):
        return self.__class__.__name__


def get_inflator():
    return Inflector()
