package main

import (
	"context"
	"encoding/json"
	"fmt"

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

func newToolsCommand(opts *options) *cobra.Command {
	var schemas bool

	cmd := &cobra.Command{
		Use:   "tools",
		Short: "Print the MCP tools this server would expose",
		Long: `Print the MCP tools this server would expose.

Useful for checking credentials, the resolved endpoints and the generated
schemas without wiring up an MCP client.`,
		Args: cobra.NoArgs,
		RunE: func(cmd *cobra.Command, _ []string) error {
			server, err := opts.newServer()
			if err != nil {
				return err
			}

			tools, err := listTools(cmd.Context(), server)
			if err != nil {
				return err
			}

			out := cmd.OutOrStdout()
			for _, tool := range tools {
				if !schemas {
					fmt.Fprintf(out, "%s\t%s\n", tool.Name, tool.Description)
					continue
				}
				encoded, err := json.MarshalIndent(tool, "", "  ")
				if err != nil {
					return err
				}
				fmt.Fprintln(out, string(encoded))
			}
			return nil
		},
	}

	cmd.Flags().BoolVar(&schemas, "schemas", false, "print the full tool definitions including input schemas")

	return cmd
}

// listTools asks the server for its tools over an in-memory transport, which
// is the only way to see exactly what a client would see.
func listTools(ctx context.Context, server *mcp.Server) ([]*mcp.Tool, error) {
	serverTransport, clientTransport := mcp.NewInMemoryTransports()

	serverSession, err := server.Connect(ctx, serverTransport, nil)
	if err != nil {
		return nil, err
	}
	defer serverSession.Close()

	client := mcp.NewClient(&mcp.Implementation{Name: "operation-mcp-tools", Version: version}, nil)
	clientSession, err := client.Connect(ctx, clientTransport, nil)
	if err != nil {
		return nil, err
	}
	defer clientSession.Close()

	result, err := clientSession.ListTools(ctx, nil)
	if err != nil {
		return nil, err
	}
	return result.Tools, nil
}
