"""Tests for Ross1000 SOAP envelope builder."""

from __future__ import annotations

from xml.etree import ElementTree

import pytest

from istat.ross1000.soap.envelope_builder import build_soap_envelope

SOAP_ENV_NS = "http://schemas.xmlsoap.org/soap/envelope/"
ROSS1000_NS = "http://turismows.regione.liguria.it/ws/checkinV2"

SAMPLE_XML = '<?xml version="1.0" encoding="UTF-8"?><movimenti struttura="TEST" dal="20260401" al="20260430"></movimenti>'


def _parse(xml_str: str) -> ElementTree.Element:
    return ElementTree.fromstring(xml_str.encode("utf-8"))


class TestBuildSoapEnvelope:

    def test_returns_string(self):
        result = build_soap_envelope(SAMPLE_XML)
        assert isinstance(result, str)

    def test_xml_declaration_present(self):
        result = build_soap_envelope(SAMPLE_XML)
        assert result.startswith("<?xml")

    def test_utf8_encoding_declared(self):
        result = build_soap_envelope(SAMPLE_XML)
        assert "UTF-8" in result or "utf-8" in result.lower()

    def test_root_is_soap_envelope(self):
        result = build_soap_envelope(SAMPLE_XML)
        root = _parse(result)
        assert "Envelope" in root.tag
        assert SOAP_ENV_NS in root.tag

    def test_soap_header_present(self):
        result = build_soap_envelope(SAMPLE_XML)
        root = _parse(result)
        header = root.find(f"{{{SOAP_ENV_NS}}}Header")
        assert header is not None

    def test_soap_body_present(self):
        result = build_soap_envelope(SAMPLE_XML)
        root = _parse(result)
        body = root.find(f"{{{SOAP_ENV_NS}}}Body")
        assert body is not None

    def test_operation_element_in_body(self):
        result = build_soap_envelope(SAMPLE_XML, operation="inviaMovimenti")
        root = _parse(result)
        body = root.find(f"{{{SOAP_ENV_NS}}}Body")
        operation = body.find(f"{{{ROSS1000_NS}}}inviaMovimenti")
        assert operation is not None

    def test_payload_embedded_in_operation(self):
        result = build_soap_envelope(SAMPLE_XML)
        root = _parse(result)
        body = root.find(f"{{{SOAP_ENV_NS}}}Body")
        # Find any child of body
        operation = list(body)[0]
        payload_el = operation.find("payload")
        assert payload_el is not None
        assert payload_el.text is not None

    def test_no_wssecurity_header_when_no_credentials(self):
        result = build_soap_envelope(SAMPLE_XML)
        root = _parse(result)
        header = root.find(f"{{{SOAP_ENV_NS}}}Header")
        # Header should be empty when no credentials provided
        assert len(list(header)) == 0

    def test_wssecurity_header_added_when_credentials_provided(self):
        result = build_soap_envelope(
            SAMPLE_XML,
            username="testuser",
            password="testpass",
        )
        root = _parse(result)
        header = root.find(f"{{{SOAP_ENV_NS}}}Header")
        # Header should have WS-Security element
        assert len(list(header)) > 0

    def test_custom_operation_name(self):
        result = build_soap_envelope(SAMPLE_XML, operation="customOperation")
        root = _parse(result)
        body = root.find(f"{{{SOAP_ENV_NS}}}Body")
        operation = body.find(f"{{{ROSS1000_NS}}}customOperation")
        assert operation is not None

    def test_envelope_is_valid_xml(self):
        result = build_soap_envelope(SAMPLE_XML)
        # Should not raise
        _parse(result)

    def test_envelope_is_valid_utf8(self):
        result = build_soap_envelope(SAMPLE_XML)
        encoded = result.encode("utf-8")
        assert isinstance(encoded, bytes)
        _parse(encoded.decode("utf-8"))
