# 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 typing import Mapping

from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent
from aws_lambda_powertools.utilities.idempotency.persistence.dynamodb import \
    DynamoDBPersistenceLayer
from voluptuous import Schema

from czc.api.v2.caching import cache_header_aware
from czc.api.v2.gateway import (authorization_context, coerce_event,
                                coerce_response, parameters,
                                serialize_response)
from czc.api.v2.idempotency import idempotency_key_aware
from czc.api.v2.testing import test_key_aware

logger = Logger()
tracer = Tracer()


def api(default_error_message: str = 'API Error', persistence_store: DynamoDBPersistenceLayer = None,
        authorization_schema: Schema = None,
        event_schema: Schema = None,
        path_schema: Schema = None,
        query_schema: Schema = None,
        ):
    """Make this Lambda Handler V2 Compliant by composing all necessary decorators

    Parameters
    ----------
    default_error_message: str, optional
        passed to @request_response(default_error_message=default_error_message)
    persistence_store: DynamoDBPersistenceLayer, optional
        passed to @idempotency_key_aware(persistence_store=persistence_store)
    authorization_schema: Schema, optional
        passed to @authorization_context(schema=authorization_schema)
    event_schema: Schema, optional
        passed to @parameters(event_schema=event_schema)
    path_schema: Schema, optional
        passed to @parameters(path_schema=path_schema)
    query_schema: Schema, optional
        passed to @parameters(query_schema=query_schema

    Returns
    -------
    Callable
        Decorated Lambda Handler
    """
    def decorator(handler):
        @tracer.capture_lambda_handler
        @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
        @coerce_event()
        @idempotency_key_aware(persistence_store=persistence_store)
        @test_key_aware()
        @serialize_response(default_error_message=default_error_message)
        @cache_header_aware()
        @coerce_response()
        @authorization_context(schema=authorization_schema)
        @parameters(event_schema=event_schema,
                    path_schema=path_schema,
                    query_schema=query_schema)
        def lambda_handler(event: APIGatewayProxyEvent, context, **kwargs) -> Mapping:
            return handler(event, context, **kwargs)
        return lambda_handler
    return decorator
