# Copyright (c) 2021 CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com

from pyfaaster.aws.exceptions import HTTPResponseException

from czc import json
from czc.api.v2.exceptions import ServiceError
from czc.logging import get_logger

logger = get_logger()


def http_response(default_error_message=None):
    """Make this Lambda Handler handle legacy response dictionaries and
    Pyfaaster Exceptions and API V2 ServiceErrors. This is a drop in replacement
    for pyfaaster.aws.handlers_decorators_v2.http_response.

    Parameters
    ----------

    Returns
    -------
    Callable
        Decorated Lambda Handler
    """

    def http_response_handler(handler):
        def handler_wrapper(event, context, **kwargs):
            try:
                res = handler(event, context, **kwargs)
                if not isinstance(res, dict):
                    raise Exception(f'Unsupported return type {type(res)}; response must be dict.')
                return {
                    'headers': res.get('headers', {}),
                    'statusCode': res.get('statusCode', 200),
                    'body': json.dumps(res['body'], iterable_as_array=True) if 'body' in res else None,
                }
            except HTTPResponseException as err:
                if err.statusCode >= 500:
                    logger.exception(err)
                else:
                    logger.warning(err)

                return {
                    'statusCode': err.statusCode,
                    'body': json.dumps(err.body, iterable_as_array=True),
                }
            except ServiceError as err:
                if err.status_code >= 500:
                    logger.exception(err)
                else:
                    logger.warning(err)
                return {
                    'statusCode': err.status_code,
                    'body': err.body,
                }
            except Exception as err:
                logger.exception(err)
                # Try and handle HTTPResponseException like objects
                if hasattr(err, 'statusCode') and hasattr(err, 'body'):
                    return {
                        'statusCode': err.statusCode,
                        'body': json.dumps(err.body, iterable_as_array=True),
                    }
                return {
                    'statusCode': 500,
                    'body': json.dumps({'error': {'message': default_error_message or 'API Error'}}, iterable_as_array=True),
                }

        return handler_wrapper

    return http_response_handler
