"""Elasticsearch MCP Server."""
from __future__ import annotations

import sys
from typing import Any

from mcp.server.fastmcp import FastMCP

from .config import load_connections
from .tools.connections import (
    auto_select_connection,
    get_current_connection as _get_current_connection,
    get_session_state,
    list_connections as _list_connections,
    select_connection as _select_connection,
)
from .tools import es_operations
from .resources.config import (
    get_es_connections_resource,
    get_es_current_resource,
    get_es_status_resource,
)


# ============== MCP Server ==============

mcp = FastMCP("Elasticsearch")


# ============== 数据模型 ==============

class ConnectionListResult:
    """连接列表结果."""
    def __init__(self, connections: list, default: str | None):
        self.connections = connections
        self.default = default


# ============== Tools ==============

@mcp.tool()
def list_connections() -> ConnectionListResult:
    """列出所有已配置的 ES 连接."""
    connections = _list_connections()
    session = get_session_state()
    default = session.current_connection

    items = [
        {
            "name": conn.name,
            "env": conn.env,
            "description": conn.description,
        }
        for conn in connections
    ]

    return ConnectionListResult(connections=items, default=default)


@mcp.tool()
def get_current_connection() -> dict:
    """获取当前选中的 ES 连接."""
    current = _get_current_connection()
    if not current:
        return {"current": None, "message": "当前没有选中的连接，请先调用 select_connection"}

    session = get_session_state()
    return {
        "current": current,
        "env": session.env,
        "es_version": session.es_version,
        "safety": {
            "read_only": session.safety.read_only if session.safety else None,
            "max_search_size": session.safety.max_search_size if session.safety else None,
        },
    }


@mcp.tool()
def select_connection(name: str) -> dict:
    """选择当前会话使用的 ES 连接."""
    result = _select_connection(name)
    return {
        "message": f"已切换到连接: {name}",
        **result,
    }


@mcp.tool()
def es_search(
    index: str,
    query: dict | None = None,
    size: int = 10,
    from_: int = 0,
) -> dict:
    """搜索 ES 文档 (from/size 分页)."""
    return es_operations.es_search(index=index, query=query, size=size, from_=from_)


@mcp.tool()
def es_scroll(
    index: str,
    query: dict | None = None,
    size: int = 100,
    scroll: str = "5m",
) -> dict:
    """滚动查询 (首次调用返回 scroll_id)."""
    return es_operations.es_scroll(index=index, query=query, size=size, scroll=scroll)


@mcp.tool()
def es_scroll_next(scroll_id: str, scroll: str = "5m") -> dict:
    """滚动查询下一页，需传入上次返回的 scroll_id."""
    return es_operations.es_scroll_next(scroll_id=scroll_id, scroll=scroll)


@mcp.tool()
def es_scroll_clear(scroll_id: str) -> dict:
    """清除滚动上下文."""
    return es_operations.es_scroll_clear(scroll_id=scroll_id)


@mcp.tool()
def es_index_doc(
    index: str,
    doc: dict,
    id_: str | None = None,
) -> dict:
    """索引文档到 ES."""
    return es_operations.es_index_doc(index=index, doc=doc, id_=id_)


@mcp.tool()
def es_update_doc(
    index: str,
    id_: str,
    doc: dict,
) -> dict:
    """更新 ES 文档."""
    return es_operations.es_update_doc(index=index, id_=id_, doc=doc)


@mcp.tool()
def es_delete_doc(
    index: str,
    id_: str,
) -> dict:
    """删除 ES 文档."""
    return es_operations.es_delete_doc(index=index, id_=id_)


@mcp.tool()
def es_bulk(
    operations: list[dict],
    refresh: bool = False,
) -> dict:
    """批量操作 (支持 index/create/update/delete)."""
    return es_operations.es_bulk(operations=operations, refresh=refresh)


@mcp.tool()
def es_create_index(
    index: str,
    mappings: dict | None = None,
    settings: dict | None = None,
) -> dict:
    """创建 ES 索引."""
    return es_operations.es_create_index(index=index, mappings=mappings, settings=settings)


@mcp.tool()
def es_delete_index(index: str) -> dict:
    """删除 ES 索引."""
    return es_operations.es_delete_index(index=index)


@mcp.tool()
def es_index_exists(index: str) -> dict:
    """检查索引是否存在."""
    return es_operations.es_index_exists(index=index)


@mcp.tool()
def es_get_index_mapping(index: str) -> dict:
    """获取索引的 mapping."""
    return es_operations.es_get_index_mapping(index=index)


@mcp.tool()
def es_list_indices() -> dict:
    """列出所有索引."""
    return es_operations.es_list_indices()


# ============== Resources ==============

@mcp.resource("es://connections")
def resource_connections() -> str:
    """获取连接列表资源."""
    import json
    return json.dumps(get_es_connections_resource(), indent=2, ensure_ascii=False)


@mcp.resource("es://current")
def resource_current() -> str:
    """获取当前连接资源."""
    import json
    return json.dumps(get_es_current_resource(), indent=2, ensure_ascii=False)


@mcp.resource("es://status")
def resource_status() -> str:
    """获取 ES MCP 状态."""
    import json
    return json.dumps(get_es_status_resource(), indent=2, ensure_ascii=False)


# ============== 入口 ==============

CONFIG_TEMPLATE = '''
MCP 配置模板 (添加到 ~/.claude/settings.json 的 mcpServers 中):

{
  "mcpServers": {
    "elasticsearch-client": {
      "command": "uvx",
      "args": ["elasticsearch-client-mcp-py"],
      "env": {
        "ES_CONNECTIONS": "[{\\"name\\":\\"your_name\\",\\"env\\":\\"prod\\",\\"url\\":\\"http://your-es:9200\\",\\"username\\":\\"elastic\\",\\"password\\":\\"your_password\\"}]"
      },
      "type": "stdio"
    }
  }
}

参数说明:
- name: 连接名称（唯一标识）
- env: 环境 (dev/test/uat/prod)
- url: ES 访问地址
- username/password: 认证信息
- safety (可选): 内联权限覆盖

profile.json 权限配置位于: ~/.config/elasticsearch-client-mcp/profile.json
环境: dev, test, uat, prod
'''


def main() -> None:
    """主入口."""
    import sys

    # 尝试加载配置
    try:
        connections = load_connections()
    except SystemExit:
        # 配置加载失败，输出配置模板
        print(CONFIG_TEMPLATE, file=sys.stderr)
        raise

    print(f"""Elasticsearch MCP Server 已启动
========================
已配置 {len(connections)} 个连接

配置来源: ES_CONNECTIONS 环境变量
权限配置: ~/.config/elasticsearch-client-mcp/profile.json
环境: dev, test, uat, prod
""", file=sys.stderr)

    # 尝试自动恢复上次连接
    auto_result = auto_select_connection()
    if auto_result:
        print(f"已自动恢复上次连接: {auto_result['name']}", file=sys.stderr)
    else:
        print("请调用 select_connection 选择要使用的连接", file=sys.stderr)

    # 运行服务
    mcp.run()


if __name__ == "__main__":
    main()
