"""DB-backed test for R6 S2's Plex per-section commit: a PlexError on a LATER library must keep the
libraries already mirrored (committed per section), not roll the whole reconcile back. Uses the DB
lane (`db` fixture) with a faked PlexClient — skipped without Postgres.
"""
from sqlalchemy import select

from app.plex import sync
from app.plex.client import PlexError
from app.models import PlexLibrary


class _FakePlex:
    def __enter__(self):
        return self

    def __exit__(self, *exc):
        return False  # don't suppress the PlexError

    def sections(self):
        return [
            {"type": "movie", "key": "1", "title": "Lib One"},
            {"type": "movie", "key": "2", "title": "Lib Two"},
        ]


def test_late_section_failure_keeps_earlier_sections(db, monkeypatch):
    monkeypatch.setattr(sync.sysconfig, "get_bool", lambda *a, **k: True)  # plex_enabled
    monkeypatch.setattr(sync, "_enabled_section_keys", lambda db: None)     # all sections wanted
    monkeypatch.setattr(sync, "PlexClient", lambda db: _FakePlex())
    monkeypatch.setattr(sync, "_sync_movies", lambda *a, **k: None)         # skip the real Plex fetch

    # Section 1 completes and commits; section 2's collections step raises → its work rolls back.
    def collections(db, plex, lib, stats):
        if lib.plex_key == "2":
            raise PlexError("boom on the second library")

    monkeypatch.setattr(sync, "_sync_collections", collections)

    result = sync.sync(db)

    assert "error" in result  # the run reports the failure honestly
    # Section 1's library survived the section-2 failure (per-section commit); section 2 rolled back.
    keys = db.scalars(select(PlexLibrary.plex_key).order_by(PlexLibrary.plex_key)).all()
    assert keys == ["1"]
