"""Tests from Lab 05. Run: pytest test_streaming_practice.py"""
import math

from streaming_practice import cut_offs, local_agreement, rewrites, send_times

# Partial results built from the lab's real flicker example
STREAM = [s.split() for s in [
    "Sandra",
    "Sancho got",
    "Sancho got up with",
    "Sancho got up with paid enough",
    "Sancho got up with pain enough in his boat",
    "Sancho got up with pain enough in his bones",
]]


def test_real_time_send_schedule():
    t = send_times(5)
    assert len(t) == 5 and all(math.isclose(a, b) for a, b in zip(t, [0.0, 0.08, 0.16, 0.24, 0.32]))


def test_appending_is_not_rewriting():
    screens = [["a"], ["a", "copy"], ["a", "copy", "of"]]
    assert rewrites(screens) == (0, 3)


def test_flicker_is_counted():
    # Sandra -> Sancho, paid -> pain, boat -> bones
    changed, shown = rewrites(STREAM)
    assert changed == 3
    assert shown == 12


def test_a_shorter_screen_rewrites_the_dropped_words():
    assert rewrites([["see", "you", "soon"], ["see"]]) == (2, 3)


def test_local_agreement_never_takes_words_back():
    committed = local_agreement(STREAM)
    assert len(committed) == len(STREAM)
    for before, after in zip(committed, committed[1:]):
        assert after[:len(before)] == before


def test_local_agreement_removes_the_flicker():
    committed = local_agreement(STREAM)
    assert rewrites(committed)[0] == 0
    assert committed[-1] == "Sancho got up with pain enough in his".split()


def test_stability_costs_latency():
    committed = local_agreement(STREAM)
    # the first word only appears once two guesses agree on it
    assert committed[0] == [] and committed[1] == []
    assert committed[2][:1] == ["Sancho"]


def test_silence_timer_cuts_off_long_pauses():
    pauses = [0.4, 0.8, 1.5, 3.0]
    assert cut_offs(pauses, 1000) == [False, False, True, True]
    assert cut_offs(pauses, 300) == [True, True, True, True]
    assert cut_offs(pauses, 3500) == [False, False, False, False]
