"""Tests for init/shutdown lifecycle."""

import anthropic
import openai

import caliper


def _reset_caliper():
    """Reset module-level state between tests."""
    caliper._initialized = False
    caliper._buffer = None


def test_init_patches_methods(tmp_path):
    _reset_caliper()
    original_create = anthropic.resources.Messages.create

    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"))
    assert anthropic.resources.Messages.create is not original_create

    caliper.shutdown()
    assert anthropic.resources.Messages.create is original_create
    _reset_caliper()


def test_shutdown_restores_all_methods(tmp_path):
    _reset_caliper()
    orig_create = anthropic.resources.Messages.create
    orig_stream = anthropic.resources.Messages.stream
    orig_async_create = anthropic.resources.AsyncMessages.create
    orig_async_stream = anthropic.resources.AsyncMessages.stream

    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"))
    caliper.shutdown()

    assert anthropic.resources.Messages.create is orig_create
    assert anthropic.resources.Messages.stream is orig_stream
    assert anthropic.resources.AsyncMessages.create is orig_async_create
    assert anthropic.resources.AsyncMessages.stream is orig_async_stream
    _reset_caliper()


def test_init_is_idempotent(tmp_path):
    _reset_caliper()
    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"))
    first_buffer = caliper._buffer

    caliper.init(target="dev", file_path=str(tmp_path / "test2.jsonl"))
    assert caliper._buffer is first_buffer  # Same buffer, not replaced

    caliper.shutdown()
    _reset_caliper()


def test_shutdown_is_idempotent(tmp_path):
    _reset_caliper()
    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"))
    caliper.shutdown()
    caliper.shutdown()  # Should not raise
    _reset_caliper()


def test_shutdown_without_init():
    _reset_caliper()
    caliper.shutdown()  # Should not raise


def test_dev_target_creates_dev_handler(tmp_path):
    _reset_caliper()
    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"))
    assert caliper._buffer is not None

    caliper.shutdown()
    _reset_caliper()


def test_last_request_id_in_public_api():
    assert hasattr(caliper, "last_request_id")
    assert callable(caliper.last_request_id)


def test_annotate_in_public_api():
    assert hasattr(caliper, "annotate")
    assert callable(caliper.annotate)


def test_annotate_before_init_is_noop():
    _reset_caliper()
    # Should not raise even when not initialized
    caliper.annotate(sentiment="positive")


def test_annotate_empty_metadata_is_noop(tmp_path):
    _reset_caliper()
    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"))
    # Empty metadata should be a no-op
    caliper.annotate()
    caliper.shutdown()
    _reset_caliper()


def test_version_exists():
    assert hasattr(caliper, "__version__")
    assert isinstance(caliper.__version__, str)
    assert len(caliper.__version__) > 0


def test_patch_anthropic_false_skips_patching(tmp_path):
    _reset_caliper()
    original_create = anthropic.resources.Messages.create

    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"), patch_anthropic=False)
    assert anthropic.resources.Messages.create is original_create

    caliper.shutdown()
    _reset_caliper()


def test_init_patches_openai_methods(tmp_path):
    _reset_caliper()
    original_create = openai.resources.chat.Completions.create

    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"))
    assert openai.resources.chat.Completions.create is not original_create

    caliper.shutdown()
    assert openai.resources.chat.Completions.create is original_create
    _reset_caliper()


def test_shutdown_restores_openai_methods(tmp_path):
    _reset_caliper()
    orig_sync = openai.resources.chat.Completions.create
    orig_async = openai.resources.chat.AsyncCompletions.create

    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"))
    caliper.shutdown()

    assert openai.resources.chat.Completions.create is orig_sync
    assert openai.resources.chat.AsyncCompletions.create is orig_async
    _reset_caliper()


def test_patch_openai_false_skips_patching(tmp_path):
    _reset_caliper()
    original_create = openai.resources.chat.Completions.create

    caliper.init(target="dev", file_path=str(tmp_path / "test.jsonl"), patch_openai=False)
    assert openai.resources.chat.Completions.create is original_create

    caliper.shutdown()
    _reset_caliper()
