"""Tests for the MCP server tools."""

import json
import tempfile
from pathlib import Path

import pytest

from tokennuke.server import create_server


@pytest.fixture
def sample_project():
    """Create a temporary project directory with sample files."""
    with tempfile.TemporaryDirectory() as tmpdir:
        # Python file
        (Path(tmpdir) / 'main.py').write_text('''
"""Main module."""

MAX_RETRIES = 3

class App:
    """Application class."""

    def run(self):
        """Start the app."""
        self.setup()
        self.serve()

    def setup(self):
        """Initialize components."""
        pass

    def serve(self):
        """Start serving requests."""
        pass

def create_app():
    """Factory function."""
    app = App()
    return app
''')

        # Another Python file
        (Path(tmpdir) / 'utils.py').write_text('''
"""Utility functions."""

def format_response(data: dict) -> str:
    """Format data as JSON response."""
    import json
    return json.dumps(data)

def validate_input(value: str) -> bool:
    """Validate user input."""
    return bool(value and value.strip())
''')

        yield tmpdir


class TestServerTools:
    """Test the MCP server tools via direct function calls."""

    def test_index_folder(self, sample_project):
        server = create_server(data_dir=tempfile.mkdtemp())
        # Access the tool function directly
        tools = {t.name: t for t in server._tool_manager.list_tools()}
        assert 'index_folder' in tools

    def test_full_workflow(self, sample_project):
        """Integration test: index -> search -> get_symbol."""
        data_dir = tempfile.mkdtemp()
        server = create_server(data_dir=data_dir)

        # We need to call the tools through the server's internal registry.
        # For testing, we import and call the underlying functions directly.
        from tokennuke.server import (
            _get_data_dir, _repo_id_from_path, _walk_source_files,
            _index_files, _get_db,
        )
        from tokennuke.storage.database import Database

        folder = Path(sample_project).resolve()
        repo_id = _repo_id_from_path(str(folder))
        db_path = Path(data_dir) / 'repos' / f'{repo_id}.db'
        db = Database(db_path)

        # Store metadata
        db.conn.execute(
            'INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)',
            ('repo_path', str(folder)),
        )
        db.conn.execute(
            'INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)',
            ('repo_name', folder.name),
        )
        db.conn.commit()

        files = _walk_source_files(folder)
        assert len(files) == 2  # main.py and utils.py

        stats = _index_files(db, folder, files, embed=False)
        assert stats['indexed'] == 2
        assert stats['symbols'] > 0

        # Search
        results = db.search_symbols_fts('App')
        assert len(results) > 0

        # Get symbol
        sym = db.get_symbol_by_qualified_name('App')
        assert sym is not None
        assert sym['kind'] == 'class'

        # File outline
        outline = db.file_outline('main.py')
        assert len(outline) > 0
        names = {s['name'] for s in outline}
        assert 'App' in names
        assert 'run' in names

        # Stats
        st = db.get_stats()
        assert st['files'] == 2
        assert st['symbols'] > 5

        db.close()
