import json
import logging

from aiohttp import web
from marshmallow import ValidationError

from maps_adv.manul.lib.data_managers.exceptions import (
    ClientExists,
    ClientNotFound,
    OrderNotFound,
)
from maps_adv.manul.proto.errors_pb2 import Error

logger = logging.getLogger(__name__)


@web.middleware
async def handle_validation_exception(request, handler):
    try:
        return await handler(request)
    except ValidationError as exc:
        logger.error("Serialization error: %s", exc.normalized_messages())
        error = Error(
            code=Error.DATA_VALIDATION_ERROR, description=json.dumps(exc.messages)
        )
        return web.Response(status=400, body=error.SerializeToString())


@web.middleware
async def handle_client_exists_exception(request, handler):
    try:
        return await handler(request)
    except ClientExists as exc:
        logger.exception(exc)
        error = Error(code=Error.CLIENT_EXISTS)
        return web.Response(status=400, body=error.SerializeToString())


@web.middleware
async def handle_client_not_found_exception(request, handler):
    try:
        return await handler(request)
    except ClientNotFound as exc:
        logger.exception(exc)
        error = Error(code=Error.CLIENT_NOT_FOUND)
        return web.Response(status=404, body=error.SerializeToString())


@web.middleware
async def handle_order_not_found_exception(request, handler):
    try:
        return await handler(request)
    except OrderNotFound as exc:
        logger.exception(exc)
        error = Error(code=Error.ORDER_NOT_FOUND)
        return web.Response(status=404, body=error.SerializeToString())
