# coding:utf-8
import traceback

from makit.web.context import Context
from makit.web.exceptions import HttpUnauthorizedException, HttpNotFoundException, HttpForbiddenException
from makit.web.middleware.base import Middleware
from makit.web.utils import error


class HandleServerError(Middleware):
    def __init__(self, error_handler=None):
        super().__init__()
        self.error_handler = error_handler

    async def __call__(self, c: Context):
        app = c.app
        try:
            await c.next()
            if not c.response_completed:
                await c.respond_json(dict(message='OK', succeeded=True))
        except HttpUnauthorizedException as e:
            await c.respond_json(str(e), status_code=401)
        except HttpNotFoundException as e:
            await c.respond_json(str(e), status_code=404)
        except HttpForbiddenException as e:
            await c.respond_json(str(e), status_code=e.status_code)
        except Exception as exc:
            try:
                c.exception = exc
                logger = app.logger
                tb = traceback.format_exc()
                logger.debug(tb)
                sys_config = app.config.APP
                await app.handle_server_error(c, exc)
                debug = sys_config.debug
                if debug:
                    return await self.debug_response(c, exc)
                else:
                    await c.respond_json('Internal Server Error', status_code=500)
            except:
                await c.respond_json('Internal Server Error', status_code=500)

    async def debug_response(self, c: Context, exc):
        accept = c.headers.get("accept", "")
        if "text/html" in accept:
            content = error.generate_html(exc)
            return await c.respond_html(content, status_code=500)
        content = error.fmt_text(exc)
        return await c.respond_text(content, status_code=500)
