from tools.pipeline.manifest import upsert_clip, add_ring_scale, rebuild_ring_edges


def _base():
    return {"clips": [{"id": "cosmos", "title": "Cosmos"}],
            "ring": {"scales": [{"id": "cosmos", "clip_id": "cosmos"}],
                     "transitions": []}}


def test_upsert_clip_replaces_by_id_else_appends():
    m = _base()
    m = upsert_clip(m, {"id": "reef", "title": "Reef"})
    assert [c["id"] for c in m["clips"]] == ["cosmos", "reef"]
    m = upsert_clip(m, {"id": "reef", "title": "Coral Reef"})   # replace, not dup
    assert [c["id"] for c in m["clips"]] == ["cosmos", "reef"]
    assert m["clips"][1]["title"] == "Coral Reef"


def test_add_ring_scale_inserts_after_named_scale():
    m = _base()
    m = add_ring_scale(m, "orbit", "orbit", after="cosmos")
    assert [s["id"] for s in m["ring"]["scales"]] == ["cosmos", "orbit"]


def test_rebuild_ring_edges_one_transition_per_edge_with_wrap():
    m = _base()
    m = add_ring_scale(m, "orbit", "orbit", after="cosmos")
    m = add_ring_scale(m, "abyss", "abyss", after="orbit")
    m = rebuild_ring_edges(m)
    files = [t["file"] for t in m["ring"]["transitions"]]
    assert files == [
        "transitions/cosmos-orbit.mp4",
        "transitions/orbit-abyss.mp4",
        "transitions/abyss-cosmos.mp4",     # wrap edge
    ]


def test_add_ring_scale_appends_when_after_missing():
    m = _base()
    m = add_ring_scale(m, "abyss", "abyss", after="nope")
    assert [s["id"] for s in m["ring"]["scales"]] == ["cosmos", "abyss"]


def test_rebuild_ring_edges_single_scale_self_wrap():
    m = _base()                       # one scale: cosmos
    m = rebuild_ring_edges(m)
    assert [t["file"] for t in m["ring"]["transitions"]] == ["transitions/cosmos-cosmos.mp4"]
