"""
Tests for Phase 7 AI config service.

Covers:
  - D-04: load_provider_config() reads from system_settings table
  - D-05: API key HKDF encryption round-trip

Plan 07-03 promotes: test_api_key_encrypt_decrypt, test_load_provider_config.
"""
import os
import pytest


# ---------------------------------------------------------------------------
# test_api_key_encrypt_decrypt — D-05 HKDF encryption round-trip
# ---------------------------------------------------------------------------

def test_api_key_encrypt_decrypt():
    """encrypt_api_key + decrypt_api_key round-trip returns original plaintext.

    Also verifies domain salt isolation: different provider_ids produce different
    ciphertexts from the same master key and plaintext (T-07-02).
    """
    from services.ai_config import encrypt_api_key, decrypt_api_key

    # Use a 32-byte master key (CLOUD_CREDS_KEY is Base64-encoded in production,
    # but the helpers accept raw bytes — use ASCII bytes for simplicity here)
    master_key = b"a" * 32  # 32 bytes deterministic test key

    # Round-trip: encrypt then decrypt must return original plaintext
    plaintext = "sk-test-api-key-abc123"
    ciphertext = encrypt_api_key(master_key, "openai", plaintext)
    recovered = decrypt_api_key(master_key, "openai", ciphertext)
    assert recovered == plaintext, "Decrypted value must match original plaintext"

    # Domain salt isolation: same key + same plaintext, different provider_id → different ciphertext
    ciphertext_anthropic = encrypt_api_key(master_key, "anthropic", plaintext)
    assert ciphertext != ciphertext_anthropic, (
        "Different provider_ids must produce different ciphertexts "
        "(HKDF salt isolation — T-07-02)"
    )

    # Cross-provider decrypt must fail (Fernet raises InvalidToken)
    from cryptography.fernet import InvalidToken
    with pytest.raises(InvalidToken):
        decrypt_api_key(master_key, "anthropic", ciphertext)  # openai key, anthropic provider_id


# ---------------------------------------------------------------------------
# test_load_provider_config — D-04 DB integration (skipped without PostgreSQL)
# ---------------------------------------------------------------------------

@pytest.mark.skipif(
    not os.getenv("INTEGRATION"),
    reason="needs PostgreSQL — set INTEGRATION=1 to run",
)
@pytest.mark.asyncio
async def test_load_provider_config(db_session):
    """load_provider_config() reads the active row from system_settings and decrypts the api_key.

    Requires a live PostgreSQL session (db_session fixture from conftest.py).
    Run with: INTEGRATION=1 pytest tests/test_ai_config.py::test_load_provider_config
    """
    pytest.importorskip("psycopg")

    from services.ai_config import encrypt_api_key, load_provider_config
    from db.models import SystemSettings
    import uuid

    master_key = b"b" * 32  # deterministic test key
    test_api_key = "sk-integration-test-key"
    provider_id = f"test-provider-{uuid.uuid4().hex[:8]}"

    # Encrypt the API key
    api_key_enc = encrypt_api_key(master_key, provider_id, test_api_key)

    # Insert a SystemSettings row with is_active=True
    row = SystemSettings(
        provider_id=provider_id,
        api_key_enc=api_key_enc,
        base_url="https://api.example.com/v1",
        model_name="test-model",
        context_chars=64000,
        is_active=True,
    )
    db_session.add(row)
    await db_session.flush()

    # Patch settings.cloud_creds_key to match our test master key
    from unittest.mock import patch
    with patch("services.ai_config.settings") as mock_settings:
        mock_settings.cloud_creds_key = master_key.decode("utf-8")
        result = await load_provider_config(db_session)

    assert result is not None, "load_provider_config must return a ProviderConfig"
    assert result.provider_id == provider_id
    assert result.api_key == test_api_key, "api_key must be decrypted correctly"
    assert result.base_url == "https://api.example.com/v1"
    assert result.model == "test-model"
    assert result.context_chars == 64000
