"""Testy magazynu widoków: identyfikator z treści i rodowód podmianek.

Podmianka (present_data z `replaces`) nie może nadpisywać treści pod starym hashem —
nagranie zrobione przed podmianką jest jeszcze w kolejce transkrypcji i jego xpathy
odnoszą się do starego drzewa.
"""

from __future__ import annotations

import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from lib import last_view                                                  # noqa: E402

HTML_A = '<div id="a">jeden</div>'
HTML_B = '<div id="b">dwa</div>'
HTML_C = '<div id="c">trzy</div>'


@pytest.fixture(autouse=True)
def clean_store():
    """Czysty magazyn na każdy test — moduł trzyma stan globalnie."""
    last_view._views.clear()
    last_view._replacements.clear()
    last_view._last_hash = None
    yield
    last_view._views.clear()
    last_view._replacements.clear()
    last_view._last_hash = None


# ------------------------------------------------------------------ identyfikator

def test_same_content_gives_same_hash():
    assert last_view.compute_page_hash(HTML_A, "js") == last_view.compute_page_hash(HTML_A, "js")


def test_js_is_part_of_identity():
    """Ten sam HTML z innym JS to inny widok — inaczej podmianka JS byłaby niewidoczna."""
    assert last_view.compute_page_hash(HTML_A, "a()") != last_view.compute_page_hash(HTML_A, "b()")


def test_store_returns_hash_of_stored_view():
    page_hash = last_view.store(HTML_A)

    assert page_hash == last_view.compute_page_hash(HTML_A)
    assert last_view.get_html(page_hash) == HTML_A
    assert last_view.is_known(page_hash)


def test_unknown_hash_is_not_known():
    last_view.store(HTML_A)

    assert not last_view.is_known("nie-ma-takiego")


def test_get_last_hash_points_at_last_stored():
    last_view.store(HTML_A)
    second = last_view.store(HTML_B)

    assert last_view.get_last_hash() == second
    assert last_view.get_html(last_view.get_last_hash()) == HTML_B


def test_get_last_hash_is_none_on_empty_store():
    assert last_view.get_last_hash() is None


# ------------------------------------------------------------------ rodowód podmianek

def test_replacement_keeps_the_old_view():
    """Stary widok musi zostać: nagranie zrobione przed podmianką wciąż go używa."""
    old = last_view.store(HTML_A)
    new = last_view.store(HTML_B, replaces=old)

    assert old != new
    assert last_view.get_html(old) == HTML_A
    assert last_view.get_html(new) == HTML_B


def test_replaced_by_names_the_successor():
    old = last_view.store(HTML_A)
    new = last_view.store(HTML_B, replaces=old)

    assert last_view.replaced_by(old) == new
    assert last_view.replaced_by(new) is None


def test_replaced_by_follows_whole_chain():
    """Agent może trzymać hash z początku łańcucha — interesuje go ten aktualny."""
    first = last_view.store(HTML_A)
    second = last_view.store(HTML_B, replaces=first)
    third = last_view.store(HTML_C, replaces=second)

    assert last_view.replaced_by(first) == third
    assert last_view.current_hash(first) == third


def test_current_hash_of_untouched_view_is_itself():
    page_hash = last_view.store(HTML_A)

    assert last_view.current_hash(page_hash) == page_hash


def test_current_hash_survives_a_cycle():
    """Odtworzenie wcześniejszej treści zamyka łańcuch w pętlę — to nie może zawiesić."""
    first = last_view.store(HTML_A)
    second = last_view.store(HTML_B, replaces=first)
    again = last_view.store(HTML_A, replaces=second)   # ta sama treść -> znów hash `first`

    assert again == first
    assert last_view.current_hash(first) in {first, second}


def test_replacing_with_identical_content_records_nothing():
    """Podmianka na tę samą treść to brak zmiany — nie ma następcy do zapamiętania."""
    page_hash = last_view.store(HTML_A)
    same = last_view.store(HTML_A, replaces=page_hash)

    assert same == page_hash
    assert last_view.replaced_by(page_hash) is None
