# tests/senarios/test_guardrails.py

import logging
import numpy as np
from beautyspot import Spot
from beautyspot.db import SQLiteTaskDB


def test_large_data_warning(tmp_path, caplog):
    """
    save_blob=None (デフォルト) の状態で閾値を超えるデータを返した時、
    WarningOnlyPolicy が機能して警告ログが出るか検証する。
    """
    # 閾値を小さく設定 (1KB)
    # ※ Spot はファクトリ関数経由で初期化されている想定
    project = Spot(
        name="guard_test",
        db=SQLiteTaskDB(tmp_path / "test.db"),
        blob_warning_threshold=1024,  # WarningOnlyPolicy に渡される
    )

    # [修正] save_blob=False を削除し、デフォルト(None)にする
    # これにより storage_policy.should_save_as_blob() が呼ばれる
    @project.mark
    def heavy_task():
        # 2KBのデータ
        return "x" * 2048

    # 実行してログをキャプチャ
    with caplog.at_level(logging.WARNING):
        res = heavy_task()

    assert len(res) == 2048
    assert "Large data detected" in caplog.text


def test_msgpack_consistency(tmp_path):
    """
    save_blob=False でも Numpy などのカスタム型が
    (Base64経由で) 壊れずに保存・復元できるか検証する。
    -> Base64ではなくNative BLOBになったため、それも含めて検証
    """
    project = Spot(name="consistency_test", db=SQLiteTaskDB(tmp_path / "test.db"))

    # Numpy用のシリアライザ登録
    project.register_type(
        np.ndarray,
        10,
        lambda x: x.tobytes(),
        lambda b: np.frombuffer(b, dtype=np.int64),
    )

    @project.mark(save_blob=False)  # あえて False
    def numpy_task():
        # int64 * 3 (24bytes) なので 1KB 以下
        return np.array([1, 2, 3], dtype=np.int64)

    # 実行 & 保存
    res1 = numpy_task()
    assert isinstance(res1, np.ndarray)

    # キャッシュからの復元 (再実行)
    res2 = numpy_task()
    assert isinstance(res2, np.ndarray)  # 文字列ではなくndarrayで戻るはず
    assert np.array_equal(res1, res2)
