"""§4.2: apply_official_exercise_media_rules — Lifecycle, Sichtbarkeit, Copyright."""
from __future__ import annotations

import os
from unittest.mock import MagicMock

import pytest
from fastapi import HTTPException

os.environ.setdefault("SKIP_DB_MIGRATE", "1")

from routers.exercises import apply_official_exercise_media_rules


def _row(
    aid: int,
    *,
    vis: str = "private",
    lifecycle: str = "active",
    copyright_notice: str | None = "",
    name: str = "f.bin",
) -> dict:
    return {
        "id": aid,
        "visibility": vis,
        "club_id": 1,
        "lifecycle_state": lifecycle,
        "copyright_notice": copyright_notice,
        "original_filename": name,
    }


def test_non_official_visibility_noop() -> None:
    cur = MagicMock()
    apply_official_exercise_media_rules(
        cur,
        1,
        "private",
        promote_attached_media=False,
        default_official_media_copyright=None,
    )
    cur.execute.assert_not_called()


def test_lifecycle_not_active_422() -> None:
    cur = MagicMock()
    cur.fetchall.return_value = [_row(1, lifecycle="trash_soft", copyright_notice="abc")]
    with pytest.raises(HTTPException) as ei:
        apply_official_exercise_media_rules(
            cur,
            1,
            "official",
            promote_attached_media=False,
            default_official_media_copyright=None,
        )
    assert ei.value.status_code == 422
    assert ei.value.detail["code"] == "OFFICIAL_MEDIA_LIFECYCLE"


def test_visibility_promotion_confirm_422() -> None:
    cur = MagicMock()
    cur.fetchall.return_value = [_row(1, vis="club", copyright_notice="halten")]
    with pytest.raises(HTTPException) as ei:
        apply_official_exercise_media_rules(
            cur,
            1,
            "official",
            promote_attached_media=False,
            default_official_media_copyright=None,
        )
    assert ei.value.status_code == 422
    assert ei.value.detail["code"] == "OFFICIAL_MEDIA_CONFIRM_REQUIRED"
    assert ei.value.detail["assets_need_visibility_promotion"]


def test_copyright_required_422() -> None:
    cur = MagicMock()
    cur.fetchall.return_value = [_row(1, vis="official", copyright_notice="")]
    with pytest.raises(HTTPException) as ei:
        apply_official_exercise_media_rules(
            cur,
            1,
            "official",
            promote_attached_media=True,
            default_official_media_copyright=None,
        )
    assert ei.value.status_code == 422
    assert ei.value.detail["code"] == "OFFICIAL_MEDIA_CONFIRM_REQUIRED"
    assert ei.value.detail["assets_missing_copyright"]


def test_promote_and_fill_copyright_updates() -> None:
    cur = MagicMock()
    cur.fetchall.return_value = [_row(1, vis="private", copyright_notice="  ")]
    apply_official_exercise_media_rules(
        cur,
        42,
        "official",
        promote_attached_media=True,
        default_official_media_copyright="© Test Holding",
    )
    assert cur.execute.call_count == 3
    sql1 = cur.execute.call_args_list[1][0][0]
    sql2 = cur.execute.call_args_list[2][0][0]
    assert "visibility = 'official'" in sql1
    assert "copyright_notice" in sql2

