import copy

import pytest

from ocpi_payloads import (
    map_incoming_payload,
    map_outgoing_payload,
    module_is_supported,
)


def test_map_incoming_normalizes_aliases_for_commands():
    raw_payload = {
        "locationId": "LOC-1",
        "connectorId": "3",
        "authorizationId": "AUTH-42",
        "nested": {"chargingProfile": {"stack_level": 1}},
    }

    mapping = map_incoming_payload("commands", "2.1.1", raw_payload, validate_required=False)

    assert mapping.error is None
    assert mapping.missing_fields == ()
    assert mapping.payload["location_id"] == "LOC-1"
    assert mapping.payload["connector_id"] == "3"
    assert mapping.payload["authorization_id"] == "AUTH-42"
    assert mapping.payload["nested"]["charging_profile"]["stack_level"] == 1


def test_map_incoming_reports_missing_required_fields():
    mapping = map_incoming_payload("locations", "2.3", {})

    assert "id" in mapping.missing_fields


def test_outgoing_payload_produces_new_instances():
    payload = {"evses": [{"uid": "1", "connectors": [{"connector_id": 1}]}]}
    clone = copy.deepcopy(payload)

    mapped = map_outgoing_payload("locations", "2.2", payload)

    assert mapped is not payload
    assert mapped == clone
    assert mapped["evses"][0]["connectors"][0]["connector_id"] == 1


@pytest.mark.parametrize(
    ("version", "module", "supported"),
    [
        ("2.1.1", "chargingprofiles", False),
        ("2.2", "chargingprofiles", True),
        ("2.1.1", "commands", True),
    ],
)
def test_module_support_matrix(version, module, supported):
    assert module_is_supported(version, module) is supported


def test_map_incoming_locations_renames_evse_fields():
    payload = {"evses": [{"evseId": "E-42", "connectors": [{"connectorId": "3"}]}]}

    mapping = map_incoming_payload("locations", "2.2", payload, validate_required=False)

    evse = mapping.payload["evses"][0]
    assert "evseId" not in evse
    assert evse["evse_uid"] == "E-42"
    assert "connectorId" not in evse["connectors"][0]
    assert evse["connectors"][0]["connector_id"] == "3"


@pytest.mark.parametrize("version", ["2.1.1", "2.2", "2.3"])
def test_required_location_fields_per_version(version):
    mapping = map_incoming_payload("locations", version, {})

    assert mapping.missing_fields == ("id",)


@pytest.mark.parametrize("version", ["2.1.1", "2.2", "2.3"])
def test_required_token_fields_per_version(version):
    mapping = map_incoming_payload("tokens", version, {"uid": "ABC"})

    assert mapping.missing_fields == ("type",)
