"""
Obsideo Cloud Drive MCP server — exposes save_memory, load_memory, get_usage.

Reads:
  OBSIDEO_API_KEY        (required)  — from Claude Desktop mcpServers env config
  OBSIDEO_ENCRYPTION_KEY             — optional; generated and saved on first use
"""

import asyncio

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import TextContent, Tool

from . import client as cs

server = Server("obsideo-cloud-drive")


@server.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="save_memory",
            description=(
                "Save a memory to Obsideo Cloud Drive. "
                "Content is AES-256-GCM encrypted on this machine before upload. "
                "Use a short, descriptive key (e.g. 'project-notes', 'todo-list')."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "key":     {"type": "string", "description": "Identifier for this memory"},
                    "content": {"type": "string", "description": "Text content to store"},
                },
                "required": ["key", "content"],
            },
        ),
        Tool(
            name="load_memory",
            description=(
                "Load a memory from Obsideo Cloud Drive. "
                "Content is decrypted locally after download."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "key": {"type": "string", "description": "Identifier of the memory to load"},
                },
                "required": ["key"],
            },
        ),
        Tool(
            name="get_usage",
            description="Show storage quota usage for this Obsideo Cloud Drive account.",
            inputSchema={
                "type": "object",
                "properties": {},
            },
        ),
    ]


@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    try:
        if name == "save_memory":
            def _save():
                cs._ensure_wallet_registered()
                return cs._request("POST", "/save", {
                    "key":     arguments["key"],
                    "content": cs._encrypt(arguments["content"]),
                })
            result   = await asyncio.to_thread(_save)
            used_mb  = result.get("bytes_used", 0) / 1024 ** 2
            quota_mb = result.get("quota_bytes", 0) / 1024 ** 2
            text = f"Saved — key: {result['key']}  used: {used_mb:.1f} MB / {quota_mb:.0f} MB"
            for w in result.get("warnings", []):
                text += f"\nWARNING: {w['message']}"
            return [TextContent(type="text", text=text)]

        elif name == "load_memory":
            result = await asyncio.to_thread(cs._request, "GET", f"/load/{arguments['key']}")
            return [TextContent(type="text", text=cs._decrypt(result["content"]))]

        elif name == "get_usage":
            data     = await asyncio.to_thread(cs._request, "GET", "/usage")
            used_mb  = data["bytes_used"] / 1024 ** 2
            quota_mb = data["quota_bytes"] / 1024 ** 2
            pct      = data.get("percent_used", 0) * 100
            return [TextContent(type="text", text=f"{used_mb:.1f} MB / {quota_mb:.0f} MB ({pct:.1f}% used)")]

        else:
            return [TextContent(type="text", text=f"Unknown tool: {name}")]

    except RuntimeError as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def main() -> None:
    async with stdio_server() as (read_stream, write_stream):
        await server.run(
            read_stream,
            write_stream,
            server.create_initialization_options(),
        )


def cli() -> None:
    """Sync entry point for `obsideo-cloud-drive` console script."""
    asyncio.run(main())
