"""Teste pentru app.web.integrare_examples — modul PUR, fara I/O.

Ordinea: RED (fara implementare) -> GREEN (dupa implementare).
"""

import json

import pytest

from app.models import PrezentareIn
from app.web.integrare_examples import exemple

BASE_URL = "https://autopass.example.com"
ACCOUNT_ID = 7

RESULT = exemple(BASE_URL, ACCOUNT_ID)

LIMBAJE_OBLIGATORII = ["curl", "python", "php", "csharp", "node", "vfp_msxml", "vfp_winhttp"]


# ---------------------------------------------------------------------------
# Structura de baza
# ---------------------------------------------------------------------------


def test_toate_limbajele_prezente():
    """Toate limbajele obligatorii trebuie sa fie chei in dictionar."""
    for limbaj in LIMBAJE_OBLIGATORII:
        assert limbaj in RESULT, f"lipseste limbajul: {limbaj}"


def test_ambele_canale_per_limbaj():
    """Fiecare limbaj are atat 'prezentari' cat si 'import'."""
    for limbaj in LIMBAJE_OBLIGATORII:
        assert "prezentari" in RESULT[limbaj], f"{limbaj} lipseste canalul 'prezentari'"
        assert "import" in RESULT[limbaj], f"{limbaj} lipseste canalul 'import'"
        assert isinstance(RESULT[limbaj]["prezentari"], str), f"{limbaj}.prezentari nu e string"
        assert isinstance(RESULT[limbaj]["import"], str), f"{limbaj}.import nu e string"


# ---------------------------------------------------------------------------
# curl — prezentari
# ---------------------------------------------------------------------------


def test_snippet_curl_prezentari_contine_endpoint_si_header():
    """Snippetul curl prezentari contine URL-ul corect si header-ul X-API-Key."""
    snippet = RESULT["curl"]["prezentari"]
    assert f"{BASE_URL}/v1/prezentari" in snippet, "lipseste endpoint-ul /v1/prezentari"
    assert "X-API-Key" in snippet, "lipseste header-ul X-API-Key"
    assert "rfak_..." in snippet, "placeholder-ul cheii trebuie sa fie rfak_..."


# ---------------------------------------------------------------------------
# python — import (multipart)
# ---------------------------------------------------------------------------


def test_snippet_python_import_upload_multipart():
    """Snippetul python import foloseste multipart (files=) pe /v1/import."""
    snippet = RESULT["python"]["import"]
    assert f"{BASE_URL}/v1/import" in snippet, "lipseste endpoint-ul /v1/import"
    assert "files=" in snippet or 'files =' in snippet, "lipseste multipart files="
    assert "rfak_..." in snippet, "placeholder-ul cheii trebuie sa fie rfak_..."


# ---------------------------------------------------------------------------
# VFP — doua dialecte distincte
# ---------------------------------------------------------------------------


def test_vfp_msxml_si_winhttp_distincte():
    """vfp_msxml foloseste MSXML2.ServerXMLHTTP.6.0; vfp_winhttp foloseste WinHttp.WinHttpRequest.5.1."""
    msxml_snippet = RESULT["vfp_msxml"]["prezentari"]
    winhttp_snippet = RESULT["vfp_winhttp"]["prezentari"]

    assert "MSXML2.ServerXMLHTTP.6.0" in msxml_snippet, (
        "vfp_msxml trebuie sa foloseasca MSXML2.ServerXMLHTTP.6.0"
    )
    assert "WinHttp.WinHttpRequest.5.1" in winhttp_snippet, (
        "vfp_winhttp trebuie sa foloseasca WinHttp.WinHttpRequest.5.1"
    )
    # Distincte — nu acelasi obiect COM in ambele
    assert "MSXML2.ServerXMLHTTP.6.0" not in winhttp_snippet, (
        "vfp_winhttp nu trebuie sa contina MSXML2 (dialect gresit)"
    )
    assert "WinHttp.WinHttpRequest.5.1" not in msxml_snippet, (
        "vfp_msxml nu trebuie sa contina WinHttp (dialect gresit)"
    )


# ---------------------------------------------------------------------------
# Drift-test schema — campuri obligatorii din model
# ---------------------------------------------------------------------------


def test_payload_acopera_campurile_obligatorii_din_model():
    """Snippetul curl prezentari contine toate campurile obligatorii din PrezentareIn.

    Deriva lista din model_fields pentru a fi rezistenta la schimbari de schema.
    Campurile cu default (odometru_initial, obs, b64_image, sistem_reparat) nu sunt
    obligatorii si nu trebuie sa cauzeze drift fals.
    """
    obligatorii = {
        camp
        for camp, field in PrezentareIn.model_fields.items()
        if field.is_required()
    }
    # Obligatorii asteptate conform spec: vin, nr_inmatriculare, data_prestatie,
    # odometru_final, prestatii
    snippet = RESULT["curl"]["prezentari"]
    for camp in obligatorii:
        assert camp in snippet, f"camp obligatoriu absent din snippet: {camp}"


def test_payload_nu_include_credentiale_rar():
    """rar_credentials e OPTIONAL: snippet-ul exemplu trimite doar cheia API + datele
    prezentarii (creds-urile RAR se configureaza pe cont, nu in fiecare cerere)."""
    for limbaj in LIMBAJE_OBLIGATORII:
        snippet = RESULT[limbaj]["prezentari"]
        assert "rar_credentials" not in snippet, (
            f"{limbaj}.prezentari include rar_credentials — nu mai e necesar in payload"
        )


def test_prestatii_in_snippet_are_cod():
    """Snippetul prezentari contine cod_prestatie sau cod_op_service in payload."""
    for limbaj in LIMBAJE_OBLIGATORII:
        snippet = RESULT[limbaj]["prezentari"]
        are_cod = "cod_prestatie" in snippet or "cod_op_service" in snippet
        assert are_cod, f"{limbaj}.prezentari lipseste cod_prestatie / cod_op_service"


# ---------------------------------------------------------------------------
# Placeholder cheie
# ---------------------------------------------------------------------------


def test_placeholder_cheie_nu_e_valoare_reala():
    """Toate snippet-urile cu autentificare contin literal 'rfak_', nu o cheie reala."""
    for limbaj in LIMBAJE_OBLIGATORII:
        for canal in ["prezentari", "import"]:
            snippet = RESULT[limbaj][canal]
            assert "rfak_" in snippet, (
                f"{limbaj}.{canal} lipseste placeholder-ul rfak_ (cheie API)"
            )


# ---------------------------------------------------------------------------
# FIX-1 — C# si VFP: JSON compact (fara newline in string literal)
# ---------------------------------------------------------------------------


def test_csharp_payload_pe_o_singura_linie():
    """Snippetul C# prezentari: JSON-ul din var json = "..." e pe o singura linie.

    Un JSON multi-linie intr-un string literal C# NU compileaza.
    Verificam ca helper-ul compact produce un JSON fara newline
    si ca acel JSON compact apare in snippetul C#.
    """
    from app.web.integrare_examples import _payload_json_compact, _snippet_csharp_prezentari

    compact = _payload_json_compact(ACCOUNT_ID)
    assert "\n" not in compact, (
        "_payload_json_compact produce newline — nu e compact"
    )

    snippet = _snippet_csharp_prezentari(BASE_URL, ACCOUNT_ID)
    # JSON-ul compact (cu ghilimele escape-uite) trebuie sa fie substring in snippet
    escaped = compact.replace('"', '\\"')
    assert escaped in snippet, (
        "JSON-ul compact (escaped) nu apare in snippetul C#; "
        "probabil _snippet_csharp_prezentari inca foloseste _payload_json_str"
    )
    # Verificare directa: linia var json = "..." nu contine newline in interiorul ei
    # In C# linia se termina cu "; (ghilimea de inchidere + punct-virgula)
    for line in snippet.splitlines():
        if 'var json = "' in line:
            stripped = line.rstrip()
            # Linia trebuie sa se inchida pe acelasi rand (cu "; sau ")
            assert stripped.endswith('";') or stripped.endswith('"'), (
                f"Linia 'var json = \"...' nu se termina pe acelasi rand: {line!r}"
            )
            break
    else:
        assert False, "Linia 'var json = \"...' nu a fost gasita in snippetul C#"


def test_vfp_payload_pe_o_singura_linie():
    """Snippetul VFP prezentari (ambele dialecte): cPayload = "..." e pe o linie.

    Un string literal VFP multi-linie NU e valid.
    Verificam ambele dialecte: vfp_msxml si vfp_winhttp.
    """
    from app.web.integrare_examples import _payload_json_compact

    compact = _payload_json_compact(ACCOUNT_ID)
    # In VFP ghilimele se dubleaza
    compact_vfp = compact.replace('"', '""')

    for dialect in ("vfp_msxml", "vfp_winhttp"):
        snippet = RESULT[dialect]["prezentari"]

        # Payload-ul VFP (cu doubling) trebuie sa fie substring in snippet
        assert compact_vfp in snippet, (
            f"{dialect}: JSON-ul compact (cu \"\" doubling) nu apare in snippet; "
            "probabil inca se foloseste _payload_json_str cu indent"
        )

        # Linia cPayload = "..." nu trebuie sa contina newline in interiorul valorii
        for line in snippet.splitlines():
            if 'cPayload = "' in line:
                assert line.rstrip().endswith('"'), (
                    f"{dialect}: linia 'cPayload = \"...' nu se termina pe acelasi rand: {line!r}"
                )
                break
        else:
            assert False, f"{dialect}: linia 'cPayload = \"...' nu a fost gasita in snippet"


# ---------------------------------------------------------------------------
# FIX-2 — Node import: FormData/Blob globale, fara import din node:buffer
# ---------------------------------------------------------------------------


def test_node_import_nu_foloseste_node_buffer():
    """Snippetul Node import nu importa din 'node:buffer' si foloseste FormData globala.

    'node:buffer' nu exporta FormData — `new FormData()` ar arunca TypeError.
    In Node 18+ FormData si Blob sunt globale.
    """
    snippet = RESULT["node"]["import"]

    assert "node:buffer" not in snippet, (
        "Snippetul Node import contine 'node:buffer' — invalid, FormData nu e acolo"
    )
    assert "new FormData()" in snippet, (
        "Snippetul Node import nu contine 'new FormData()' — FormData trebuie folosita global"
    )
