# Copyright (c) 2022 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

import pytest
from aws_lambda_powertools.utilities.parser import BaseModel
from voluptuous import ALLOW_EXTRA, Schema

from czc.parser import parsed_event, uses_event_parameters


class TestEvent(BaseModel):
    __test__ = False
    field1: str
    field2: int


@pytest.mark.unit
def test_parsed_event_decorator():
    raw_event = {
        'field1': 'value1',
        'field2': 2
    }

    @parsed_event(TestEvent)
    def test_fn(event: Mapping, context: Mapping, parsed_event: TestEvent) -> TestEvent:
        return parsed_event

    returned_event: TestEvent = test_fn(raw_event, None)  # type: ignore

    assert returned_event.field1 == raw_event['field1']
    assert returned_event.field2 == raw_event['field2']


@pytest.mark.unit
@pytest.mark.parametrize('passthrough_context', [True, False])
@pytest.mark.parametrize('passthrough_event', [True, False])
@pytest.mark.parametrize('schema', [
    pytest.param(None, id='No Schema'),
    pytest.param(Schema({}, extra=ALLOW_EXTRA), id='Valid Schema'),
])
def test_uses_event_parameters_decorator(passthrough_context, passthrough_event, schema):
    raw_event = {
        'field1': 'value1',
        'field2': 2
    }

    def assert_fields(field1: str, field2: int):
        assert field1 == raw_event['field1']
        assert field2 == raw_event['field2']

    if passthrough_context and passthrough_event:
        test_fn = lambda event, context, field1, field2: assert_fields(field1, field2)
    elif passthrough_context or passthrough_event:
        test_fn = lambda event_or_context, field1, field2: assert_fields(field1, field2)
    else:
        test_fn = lambda field1, field2: assert_fields(field1, field2)

    decorated_fn = uses_event_parameters(schema=schema, passthrough_context=passthrough_context, passthrough_event=passthrough_event)(test_fn)
    decorated_fn(raw_event, None)  # type: ignore
