import sys
from pathlib import Path

from flask import Flask, request

sys.path.append(str(Path(__file__).resolve().parent))

from ocpi_payloads import map_incoming_payload
from ocpi_utils import BackendProfile, BackendRegistry, validate_json_payload, verify_token_header


def _registry_with_hosts():
    profiles = [
        BackendProfile(
            backend_id="alpha",
            hosts={"cpo.example.com"},
            modules={"locations"},
            token="alpha-token",
            default=False,
        ),
        BackendProfile(
            backend_id="beta",
            hosts=set(),
            modules={"tariffs"},
            token=None,
            default=True,
        ),
    ]
    return BackendRegistry(profiles, fallback_token="fallback-token")


def test_select_backend_prefers_header_over_host():
    app = Flask(__name__)
    registry = _registry_with_hosts()
    with app.test_request_context(
        "/ocpi/versions",
        headers={"X-OCPI-Backend": "alpha", "Host": "other.example.com"},
    ):
        profile = registry.select_backend(request)
    assert profile.backend_id == "alpha"
    assert profile.token == "alpha-token"


def test_select_backend_by_host_with_fallback_token():
    app = Flask(__name__)
    registry = _registry_with_hosts()
    with app.test_request_context("/ocpi/versions", headers={"Host": "cpo.example.com"}):
        profile = registry.select_backend(request)
    assert profile.backend_id == "alpha"
    assert profile.token == "alpha-token"

    with app.test_request_context("/ocpi/versions", headers={"Host": "unknown.test"}):
        profile = registry.select_backend(request)
    assert profile.backend_id == "beta"
    assert profile.token == "fallback-token"


def test_select_backend_filters_by_module():
    app = Flask(__name__)
    registry = _registry_with_hosts()
    with app.test_request_context("/ocpi/versions", headers={"X-Backend-ID": "alpha"}):
        profile = registry.select_backend(request, module="tariffs")
    assert profile is None

    with app.test_request_context("/ocpi/versions"):
        profile = registry.select_backend(request, module="tariffs")
    assert profile.backend_id == "beta"


def test_validate_json_payload_helpers():
    valid, missing = validate_json_payload({"id": "LOC-1"}, ["id"])
    assert valid
    assert missing is None

    valid, missing = validate_json_payload({}, ["id"])
    assert not valid
    assert missing == "id"

    valid, missing = validate_json_payload(None, ["id"])
    assert not valid
    assert missing == "JSON body is required"


def test_verify_token_header():
    app = Flask(__name__)
    with app.test_request_context("/ocpi/versions", headers={"Authorization": "Token secret"}):
        assert verify_token_header(request, "secret")
    with app.test_request_context("/ocpi/versions", headers={}):
        assert not verify_token_header(request, "secret")
    with app.test_request_context("/ocpi/versions", headers={"Authorization": "Token other"}):
        assert not verify_token_header(request, "secret")


def test_map_incoming_payload_normalizes_token_aliases():
    payload = {
        "uid": "abc-1",
        "type": "rfid",
        "authId": "AUTH-1",
        "issuer": "Pipelet",
        "whitelistStatus": "allowed",
        "contractId": "C-1",
        "visualNumber": "12345",
        "last_updated": "2024-01-01T00:00:00Z",
    }

    result = map_incoming_payload("tokens", "2.2", payload)

    assert result.missing_fields == ()
    assert result.payload["type"] == "RFID"
    assert result.payload["whitelist"] == "ALLOWED"
    assert result.payload["auth_id"] == "AUTH-1"
    assert result.payload["contract_id"] == "C-1"
    assert result.payload["visual_number"] == "12345"
