"""The committee start-camera follows starts independently of the on-air race."""
import sys
from pathlib import Path

from conftest import ll, make_course

BROADCAST = Path(__file__).resolve().parents[2]
V3 = Path(__file__).resolve().parents[3]
sys.path.insert(0, str(BROADCAST / "live"))
sys.path.insert(0, str(V3 / "scoring"))

from race_queue import select_start_camera_status  # noqa: E402
from start_progress import StartProgressTracker  # noqa: E402
from streaming_score import StreamingScorer  # noqa: E402


def _point(east: float, north: float) -> dict:
    return {**ll(east, north), "course": 0.0, "speed": 2.0}


def test_complete_start_requires_each_boat_to_cross_after_the_gun():
    tracker = StartProgressTracker(make_course([(0.0, 100.0, "M1")]), ["a", "b", "c", "d"],
                                   gun_sec=5)
    tracker.observe(5, {boat: _point(0.0, -2.0) for boat in "abcd"})
    state = tracker.observe(6, {boat: _point(0.0, 2.0) for boat in "abcd"})
    assert state == {"startedBoatIds": ["a", "b", "c", "d"], "startedBoatCount": 4,
                     "expectedBoatCount": 4, "allBoatsStarted": True,
                     "allBoatsStartedSec": 6}


def test_an_ocs_boat_is_not_started_until_it_returns_and_crosses_cleanly():
    tracker = StartProgressTracker(make_course([(0.0, 100.0, "M1")]), ["legal", "ocs"], gun_sec=5)
    tracker.observe(5, {"legal": _point(0.0, -2.0), "ocs": _point(0.0, 2.0)})
    state = tracker.observe(6, {"legal": _point(0.0, 2.0), "ocs": _point(0.0, 3.0)})
    assert state["startedBoatIds"] == ["legal"]
    tracker.observe(7, {"legal": _point(0.0, 3.0), "ocs": _point(0.0, -2.0)})
    state = tracker.observe(8, {"legal": _point(0.0, 4.0), "ocs": _point(0.0, 2.0)})
    assert state["allBoatsStarted"] is True and state["allBoatsStartedSec"] == 8


def test_live_scorer_exposes_start_progress_without_changing_standings_contract():
    boats = [("one", "One", [("a", "1"), ("b", "2")]),
             ("two", "Two", [("c", "3"), ("d", "4")])]
    from conftest import make_feed
    feed = make_feed(make_course([(0.0, 100.0, "M1")]), boats, {
        5: {boat: (0.0, -2.0, 0.0) for boat in "abcd"},
        6: {boat: (0.0, 2.0, 0.0) for boat in "abcd"},
    }, gun_sec=5)
    scorer = StreamingScorer(feed["meta"], feed["course"], feed["teams"])
    scorer.push_frame(5, feed["frames"]["5"])
    scorer.push_frame(6, feed["frames"]["6"])
    assert scorer.start_progress()["allBoatsStarted"] is True
    assert scorer.start_progress()["allBoatsStartedSec"] == 6


def test_start_camera_holds_ten_seconds_after_complete_start_then_selects_next_race():
    rows = [
        {"instanceId": "current", "gun": 100_000, "stop": None, "state": "racing",
         "name": "Race 12"},
        {"instanceId": "next", "gun": 300_000, "stop": None, "state": "armed",
         "name": "Race 13"},
    ]
    starts = {"current": 125_000}
    assert select_start_camera_status(rows, 134_999, starts)["instanceId"] == "current"
    selected = select_start_camera_status(rows, 135_000, starts)
    assert selected["instanceId"] == "next" and selected["mode"] == "next"


def test_start_camera_never_holds_a_started_race_beyond_one_minute():
    rows = [
        {"instanceId": "current", "gun": 100_000, "stop": None, "state": "racing"},
        {"instanceId": "next", "gun": 170_000, "stop": None, "state": "armed"},
    ]
    assert select_start_camera_status(rows, 159_999)["instanceId"] == "current"
    selected = select_start_camera_status(rows, 160_000)
    assert selected["instanceId"] == "next" and selected["mode"] == "countdown"


def test_future_race_switches_from_next_to_countdown_in_the_final_minute():
    rows = [{"instanceId": "r", "gun": 200_000, "stop": None, "state": "armed"}]
    assert select_start_camera_status(rows, 139_999)["mode"] == "next"
    assert select_start_camera_status(rows, 140_000)["mode"] == "countdown"
