package mcpserver

import (
	"runtime/debug"
	"strings"

	"github.com/modelcontextprotocol/go-sdk/mcp"
)

// ServerOptions 控制 MCP server 对外暴露的工具范围。
type ServerOptions struct {
	// SchemaOnly 仅暴露连接、库表、字段、索引、外键、触发器和 DDL 工具，不注册 execute_sql。
	SchemaOnly bool
}

func NewServer(backend Backend) *mcp.Server {
	return NewServerWithOptions(backend, ServerOptions{})
}

func NewServerWithOptions(backend Backend, options ServerOptions) *mcp.Server {
	server := mcp.NewServer(&mcp.Implementation{
		Name:    "gonavi-ai",
		Version: implementationVersion(),
	}, nil)

	service := NewService(backend)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_connections",
		Description: "列出当前 GoNavi 已保存的数据库连接，先调用它获取 connectionId。不会返回明文密码等敏感信息。",
	}, service.GetConnections)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_databases",
		Description: "根据 connectionId 获取数据库/Schema 列表。",
	}, service.GetDatabases)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_tables",
		Description: "根据 connectionId 和可选 dbName 获取表列表。dbName 为空时优先使用保存连接里的默认数据库。",
	}, service.GetTables)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_all_columns",
		Description: "根据 connectionId 和 dbName 获取该数据库下全部表的字段摘要，适合按字段反查表。",
	}, service.GetAllColumns)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_columns",
		Description: "根据 connectionId、可选 dbName、tableName 获取字段定义。",
	}, service.GetColumns)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_indexes",
		Description: "根据 connectionId、可选 dbName、tableName 获取索引定义。",
	}, service.GetIndexes)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_foreign_keys",
		Description: "根据 connectionId、可选 dbName、tableName 获取外键关系。",
	}, service.GetForeignKeys)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_triggers",
		Description: "根据 connectionId、可选 dbName、tableName 获取触发器定义。",
	}, service.GetTriggers)

	mcp.AddTool(server, &mcp.Tool{
		Name:        "get_table_ddl",
		Description: "根据 connectionId、可选 dbName、tableName 获取建表或建视图语句。",
	}, service.GetTableDDL)

	if !options.SchemaOnly {
		mcp.AddTool(server, &mcp.Tool{
			Name:        "execute_sql",
			Description: "执行 SQL，支持多语句结果集。执行范围受 GoNavi AI 设置中的安全控制约束；命中允许范围内的 DML/DDL 等非只读语句时，仍必须显式传 allowMutating=true。",
		}, service.ExecuteSQL)
	}

	return server
}

func implementationVersion() string {
	if info, ok := debug.ReadBuildInfo(); ok {
		version := strings.TrimSpace(info.Main.Version)
		if version != "" && version != "(devel)" {
			return version
		}
	}
	return "dev"
}
