#!/usr/bin/env python3
"""
Tests for cross-format round-trip fidelity — verifies that an object
serialized in one format and deserialized, then serialized in another
format, preserves all data correctly.

Covers: All deserialization phases (3, 4, 8, 10) and serialization phases (12, 13)
"""

import json
import sys
from pathlib import Path

project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))

from vital_ai_vitalsigns.vitalsigns import VitalSigns
from vital_ai_vitalsigns.model.VITAL_Node import VITAL_Node


def _make_rich_node():
    """Helper: create a VITAL_Node with multiple property types set."""
    vs = VitalSigns()
    node = VITAL_Node()
    node.URI = "http://example.com/xformat-test"
    node.name = "CrossFormat Test"
    node.active = True
    node.timestamp = 1710000000000
    return node


def _assert_node_values(node, label=""):
    """Assert that the node has the expected property values."""
    prefix = f"[{label}] " if label else ""
    assert str(node.URI) == "http://example.com/xformat-test", f"{prefix}URI mismatch"
    assert node.name == "CrossFormat Test", f"{prefix}name mismatch"
    assert node.active == True, f"{prefix}active mismatch"
    assert node.timestamp == 1710000000000, f"{prefix}timestamp mismatch"


def test_json_to_rdf_roundtrip():
    """Object -> JSON -> object -> RDF -> object preserves data."""
    node = _make_rich_node()

    # Serialize to JSON, deserialize
    json_str = node.to_json(pretty_print=False)
    from_json = VITAL_Node.from_json(json_str)
    _assert_node_values(from_json, "after JSON")

    # Serialize to RDF, deserialize
    rdf_str = from_json.to_rdf(format='nt')
    from_rdf = VITAL_Node.from_rdf(rdf_str)
    _assert_node_values(from_rdf, "after RDF")


def test_rdf_to_json_roundtrip():
    """Object -> RDF -> object -> JSON -> object preserves data."""
    node = _make_rich_node()

    rdf_str = node.to_rdf(format='nt')
    from_rdf = VITAL_Node.from_rdf(rdf_str)
    _assert_node_values(from_rdf, "after RDF")

    json_str = from_rdf.to_json(pretty_print=False)
    from_json = VITAL_Node.from_json(json_str)
    _assert_node_values(from_json, "after JSON")


def test_dict_to_triples_roundtrip():
    """Object -> dict -> object -> triples -> object preserves data."""
    node = _make_rich_node()

    dict_data = node.to_dict()
    from_dict = VITAL_Node.from_dict(dict_data)
    _assert_node_values(from_dict, "after dict")

    triple_list = []
    from_dict.add_to_list(triple_list)

    def gen():
        for t in triple_list:
            yield t

    from_triples = VITAL_Node.from_triples(gen())
    _assert_node_values(from_triples, "after triples")


def test_triples_to_dict_roundtrip():
    """Object -> triples -> object -> dict -> object preserves data."""
    node = _make_rich_node()

    triple_list = []
    node.add_to_list(triple_list)

    def gen():
        for t in triple_list:
            yield t

    from_triples = VITAL_Node.from_triples(gen())
    _assert_node_values(from_triples, "after triples")

    dict_data = from_triples.to_dict()
    from_dict = VITAL_Node.from_dict(dict_data)
    _assert_node_values(from_dict, "after dict")


def test_json_to_dict_roundtrip():
    """Object -> JSON -> object -> dict -> object preserves data."""
    node = _make_rich_node()

    json_str = node.to_json(pretty_print=False)
    from_json = VITAL_Node.from_json(json_str)
    _assert_node_values(from_json, "after JSON")

    dict_data = from_json.to_dict()
    from_dict = VITAL_Node.from_dict(dict_data)
    _assert_node_values(from_dict, "after dict")


def test_rdf_to_triples_roundtrip():
    """Object -> RDF -> object -> triples -> object preserves data."""
    node = _make_rich_node()

    rdf_str = node.to_rdf(format='nt')
    from_rdf = VITAL_Node.from_rdf(rdf_str)
    _assert_node_values(from_rdf, "after RDF")

    triple_list = []
    from_rdf.add_to_list(triple_list)

    def gen():
        for t in triple_list:
            yield t

    from_triples = VITAL_Node.from_triples(gen())
    _assert_node_values(from_triples, "after triples")


def test_full_chain_all_formats():
    """Object -> JSON -> dict -> RDF -> triples -> dict -> JSON -> object."""
    node = _make_rich_node()

    # JSON
    json_str = node.to_json(pretty_print=False)
    obj = VITAL_Node.from_json(json_str)
    _assert_node_values(obj, "step 1: JSON")

    # dict
    d = obj.to_dict()
    obj = VITAL_Node.from_dict(d)
    _assert_node_values(obj, "step 2: dict")

    # RDF
    rdf_str = obj.to_rdf(format='nt')
    obj = VITAL_Node.from_rdf(rdf_str)
    _assert_node_values(obj, "step 3: RDF")

    # triples
    tl = []
    obj.add_to_list(tl)
    obj = VITAL_Node.from_triples(iter(tl))
    _assert_node_values(obj, "step 4: triples")

    # Back to dict
    d = obj.to_dict()
    obj = VITAL_Node.from_dict(d)
    _assert_node_values(obj, "step 5: dict again")

    # Back to JSON
    json_str = obj.to_json(pretty_print=False)
    obj = VITAL_Node.from_json(json_str)
    _assert_node_values(obj, "step 6: JSON again")
