"""
Notes MCP Server — Lesson 13 Demo

A complete MCP server that manages notes with tools and resources.
Run with: mcp dev demo/notes_server.py
Or:       python demo/notes_server.py
"""

from mcp.server.fastmcp import FastMCP

# ── Create the server ─────────────────────────────────────────────────────
mcp = FastMCP("notes-server")

# ── In-memory note storage ────────────────────────────────────────────────
notes: dict[str, str] = {}


# ── Tools ─────────────────────────────────────────────────────────────────

@mcp.tool()
def add_note(title: str, content: str) -> str:
    """Add a new note to the collection.

    Args:
        title: Short title for the note (used as identifier)
        content: Full text content of the note
    """
    notes[title] = content
    return f"Note '{title}' saved successfully ({len(content)} characters)"


@mcp.tool()
def list_notes() -> str:
    """List all saved notes with their titles."""
    if not notes:
        return "No notes saved yet."
    return "\n".join(f"- {title}" for title in sorted(notes.keys()))


@mcp.tool()
def get_note(title: str) -> str:
    """Get the full content of a specific note.

    Args:
        title: The title of the note to retrieve
    """
    if title not in notes:
        return f"Error: note '{title}' not found. Use list_notes to see available notes."
    return notes[title]


@mcp.tool()
def search_notes(query: str) -> str:
    """Search notes by keyword (case-insensitive).

    Args:
        query: The keyword to search for in note titles and content
    """
    query_lower = query.lower()
    matches = []
    for title, content in notes.items():
        if query_lower in title.lower() or query_lower in content.lower():
            snippet = content[:100] + ("..." if len(content) > 100 else "")
            matches.append(f"- {title}: {snippet}")
    if not matches:
        return f"No notes found matching '{query}'."
    return f"Found {len(matches)} matching note(s):\n" + "\n".join(matches)


@mcp.tool()
def delete_note(title: str) -> str:
    """Delete a note by its title.

    Args:
        title: The title of the note to delete
    """
    if title not in notes:
        return f"Error: note '{title}' not found."
    del notes[title]
    return f"Note '{title}' deleted."


# ── Resources ─────────────────────────────────────────────────────────────

@mcp.resource("notes://all")
def get_all_notes() -> str:
    """All notes formatted as text."""
    if not notes:
        return "No notes saved."
    parts = [f"## {title}\n{content}" for title, content in sorted(notes.items())]
    return "\n\n".join(parts)


@mcp.resource("notes://{title}")
def get_note_resource(title: str) -> str:
    """A specific note by its title."""
    return notes.get(title, f"Note '{title}' not found.")


# ── Run ───────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    mcp.run()
