import pytest
from sqlalchemy import text
from sqlalchemy.ext.asyncio import create_async_engine

from app.database import ensure_learning_artifact_tables, ensure_memory_columns, ensure_skill_columns


@pytest.mark.anyio
async def test_ensure_memory_columns_adds_importance_tracking_fields_for_existing_user_memories_table(tmp_path):
    db_path = tmp_path / 'test_user_memories.db'
    engine = create_async_engine(f"sqlite+aiosqlite:///{db_path}", future=True)

    async with engine.begin() as conn:
        await conn.execute(text(
            '''
            CREATE TABLE user_memories (
                id VARCHAR(36) PRIMARY KEY,
                user_id VARCHAR(36) NOT NULL,
                memory_type VARCHAR(50) NOT NULL,
                content TEXT NOT NULL,
                importance INTEGER,
                is_recalled BOOLEAN,
                recall_count INTEGER,
                source_conversation_id VARCHAR(36),
                extracted_at DATETIME,
                last_recalled_at DATETIME,
                created_at DATETIME,
                updated_at DATETIME
            )
            '''
        ))
        result = await conn.execute(text("PRAGMA table_info(user_memories)"))
        columns_before = {row[1] for row in result.fetchall()}
        assert 'frequency_count' not in columns_before
        assert 'importance_score' not in columns_before
        assert 'decay_score' not in columns_before

        await ensure_memory_columns(conn)

        result = await conn.execute(text("PRAGMA table_info(user_memories)"))
        columns_after = {row[1] for row in result.fetchall()}
        assert 'frequency_count' in columns_after
        assert 'emotion_tags' in columns_after
        assert 'importance_score' in columns_after
        assert 'importance_level' in columns_after
        assert 'associated_topics' in columns_after
        assert 'decay_score' in columns_after
        assert 'is_archived' in columns_after
        assert 'last_accessed_at' in columns_after
        assert 'archive_at' in columns_after

    await engine.dispose()


@pytest.mark.anyio
async def test_ensure_skill_columns_adds_lifecycle_fields_for_existing_skills_table(tmp_path):
    db_path = tmp_path / 'test_skills.db'
    engine = create_async_engine(f"sqlite+aiosqlite:///{db_path}", future=True)

    async with engine.begin() as conn:
        await conn.execute(text(
            '''
            CREATE TABLE skills (
                id VARCHAR(36) PRIMARY KEY,
                name VARCHAR(100) NOT NULL,
                description TEXT,
                instructions TEXT NOT NULL,
                agent_type VARCHAR(50) NOT NULL,
                visibility VARCHAR(20),
                is_active BOOLEAN,
                owner_id VARCHAR(36),
                created_at DATETIME,
                updated_at DATETIME
            )
            '''
        ))
        result = await conn.execute(text("PRAGMA table_info(skills)"))
        columns_before = {row[1] for row in result.fetchall()}
        assert 'status' not in columns_before
        assert 'effectiveness' not in columns_before

        await ensure_skill_columns(conn)

        result = await conn.execute(text("PRAGMA table_info(skills)"))
        columns_after = {row[1] for row in result.fetchall()}
        assert 'status' in columns_after
        assert 'scope' in columns_after
        assert 'effectiveness' in columns_after
        assert 'review_after' in columns_after
        assert 'activation_count' in columns_after
        assert 'last_activated_at' in columns_after

    await engine.dispose()


@pytest.mark.anyio
async def test_ensure_learning_artifact_tables_creates_table_and_indexes(tmp_path):
    db_path = tmp_path / 'test_learning_artifacts.db'
    engine = create_async_engine(f"sqlite+aiosqlite:///{db_path}", future=True)

    async with engine.begin() as conn:
        await ensure_learning_artifact_tables(conn)
        result = await conn.execute(text("PRAGMA table_info(learning_artifacts)"))
        columns = {row[1] for row in result.fetchall()}
        assert 'artifact_type' in columns
        assert 'artifact_key' in columns
        assert 'summary_text' in columns
        assert 'payload' in columns

        indexes = await conn.execute(text("PRAGMA index_list(learning_artifacts)"))
        index_names = {row[1] for row in indexes.fetchall()}
        assert 'ix_learning_artifacts_user_id' in index_names
        assert 'ix_learning_artifacts_artifact_type' in index_names

    await engine.dispose()
