import asyncio
import json
from posixpath import join

import aiohttp
from redmine.utilities import is_string, to_string, json_response
from redmine.exceptions import (
    AuthError, ConflictError, ImpersonateError, ServerError, ValidationError,
    ResourceNotFoundError, RequestEntityTooLargeError, UnknownError,
    ForbiddenError, JSONDecodeError)


class AsyncRedmine:
    def __init__(self, url, *, username=None, password=None, key=None,
                 requests={}, impersonate=None):
        self.url = url.rstrip('/')
        self.username = username
        self.password = password
        self.key = key
        self.requests = requests
        self.impersonate = impersonate

    @asyncio.coroutine
    def request(self, method, url, headers=None, params=None, data=None,
                raw_response=False):
        """Make requests to Redmine and returns result in json format."""
        kwargs = dict(self.requests, **{
            'headers': headers or {},
            'params': params or {},
            'data': data or {},
        })

        if ('Content-Type' not in kwargs['headers'] and
                method in ('post', 'put')):
            kwargs['data'] = json.dumps(data)
            kwargs['headers']['Content-Type'] = 'application/json'

        if self.impersonate is not None:
            kwargs['headers']['X-Redmine-Switch-User'] = self.impersonate

        # We would like to be authenticated by API key by default
        if 'key' not in kwargs['params'] and self.key is not None:
            kwargs['params']['key'] = self.key
        else:
            kwargs['auth'] = (self.username, self.password)

        api_url = join(self.url, url + '.json')
        response = yield from aiohttp.request(method, api_url, **kwargs)

        if response.status in (200, 201):
            if raw_response:
                return response
            content = yield from response.content.read()
            if not content.strip():
                return True
            else:
                try:
                    return json.loads(content.decode('utf-8'))
                except (ValueError, TypeError):
                    raise JSONDecodeError
        elif response.status == 401:
            raise AuthError
        elif response.status == 403:
            raise ForbiddenError
        elif response.status == 404:
            raise ResourceNotFoundError
        elif response.status == 409:
            raise ConflictError
        elif response.status == 412 and self.impersonate is not None:
            raise ImpersonateError
        elif response.status == 413:
            raise RequestEntityTooLargeError
        elif response.status == 422:
            response_json = yield from response.json()
            errors = json_response(response_json)['errors']
            raise ValidationError(to_string(', '.join(e if is_string(e)
                                            else ': '.join(e)
                                            for e in errors)))
        elif response.status == 500:
            raise ServerError

        raise UnknownError(response.status)

@@ -1873,22 +1873,19 @@
         
-con
 te
-n
+x
 t = yiel
@@ -1904,20 +1904,12 @@
 nse.
-content.read
+text
 ()%0A 
@@ -1926,22 +1926,19 @@
  if not 
-con
 te
-n
+x
 t.strip(
@@ -2049,31 +2049,12 @@
 ads(
-content.decode('utf-8')
+text
 )%0A  

Use request.text instead of request.content