
import functools
from inspect import isawaitable, stack, getmodulename
from traceback import format_exc
import logging

from luya.server import LuyProtocol, serve, multiple_serve, _print_logo
from luya.response import html as response_html
from luya.response import HTTPResponse, HTTPStreamingResponse
from luya.router import Router
from luya.exception import LuyAException
import aiohttp
from json import JSONDecodeError

PORT = 23333


class LuyA_Test():
    def __init__(self, app):
        self.app = app

    async def _request(self, url='/', method='get', headers=None, data=None):
        conn = aiohttp.TCPConnector(verify_ssl=False)
        async with aiohttp.ClientSession(connector=conn) as session:
            async with getattr(
                    session, method.lower())('http://127.0.0.1:{}'.format(PORT) + url, headers=headers, data=data) as response:
                try:
                    response.text = await response.text()
                except UnicodeDecodeError as e:
                    response.text = None

                try:
                    response.json = await response.json()
                except (JSONDecodeError,
                        UnicodeDecodeError,
                        aiohttp.ClientResponseError):
                    response.json = None
                # print(response.headers)

                response.body = await response.read()
                return response

    def _run_test_server(self, url='/', method='get', headers=None, data=None):

        rsp = [None]

        async def request(app, loop):
            rsp[0] = await self._request(url=url, method=method, headers=headers, data=data)
            self.app.stop()

        self.app.listener('after_start')(request)

        self.app.run(port=PORT, debug=False)
        self.app.after_server_start.pop()  # have to pop the listener
        return rsp[0]

    def get(self, url='/', headers=None):
        return self._run_test_server(url=url, method='get', headers=headers)

    def post(self, url='/', headers=None, data='msg'):

        return self._run_test_server(url=url, method='post', headers=headers, data=data)
