from functools import wraps

from ..types import Message, Context, Response, CommandType
from ..failure import RollbotFailure, RollbotFailureException

explanations = {
    RollbotFailure.INVALID_COMMAND: "Sorry - I don't think I understand the command '!{}'... I'll try to figure it out and get back to you!",
    RollbotFailure.MISSING_SUBCOMMAND: "Sorry - !{} requires a sub-command.",
    RollbotFailure.INVALID_SUBCOMMAND: "Sorry - the sub-command you used for {} was not valid.",
    RollbotFailure.INVALID_ARGUMENTS: "Sorry - !{} cannot use those arguments!",
    RollbotFailure.SERVICE_DOWN: "Sorry - !{} relies on a service I couldn't reach!",
    RollbotFailure.PERMISSIONS: "Sorry - you don't have permission to use that command or sub-command in this chat!",
    RollbotFailure.INTERNAL_ERROR: "Sorry - I encountered an unrecoverable error, please review internal logs.",
}


def with_failure_handling(fn: CommandType) -> CommandType:
    @wraps(fn)
    async def wrapped(message: Message, context: Context):
        try:
            await fn(message, context)
        except RollbotFailureException as exc:
            explanation = explanations[exc.failure]
            if "{}" in explanation:
                explanation = explanation.format(message.command.name)
            if exc.detail is not None:
                explanation += " " + exc.detail
            await context.respond(Response.from_message(message, explanation))

    return wrapped
