package main

import (
	"context"
	"encoding/json"
	"os/exec"

	"github.com/mark3labs/mcp-go/mcp"
)

type doctorArgs struct {
	Subcommand string `json:"subcommand,omitempty"`
}

func doctorTool() mcp.Tool {
	return mcp.NewTool("fn_doctor",
		mcp.WithDescription("Run `fn doctor [subcommand] --json` and return the parsed report. Subcommands: artefacts, services, sync, uses-functions, unused. Empty = all checks. Read-only."),
		mcp.WithString("subcommand",
			mcp.Description("Subcommand. Empty runs all."),
			mcp.Enum("", "artefacts", "services", "sync", "uses-functions", "unused"),
		),
	)
}

func (d *deps) handleDoctor(ctx context.Context, _ mcp.CallToolRequest, args doctorArgs) (*mcp.CallToolResult, error) {
	bin := d.fnBin()
	cmdArgs := []string{"doctor"}
	if args.Subcommand != "" {
		cmdArgs = append(cmdArgs, args.Subcommand)
	}
	cmdArgs = append(cmdArgs, "--json")

	cmd := exec.CommandContext(ctx, bin, cmdArgs...)
	cmd.Dir = d.root
	out, err := cmd.Output()
	if err != nil {
		stderr := ""
		if ee, ok := err.(*exec.ExitError); ok {
			stderr = string(ee.Stderr)
		}
		return mcp.NewToolResultError("fn doctor: " + err.Error() + "\n" + stderr), nil
	}

	// Try to parse JSON; if it fails, return the raw output.
	var report any
	if jsonErr := json.Unmarshal(out, &report); jsonErr != nil {
		return mcp.NewToolResultText(string(out)), nil
	}
	b, _ := json.MarshalIndent(map[string]any{"subcommand": args.Subcommand, "report": report}, "", "  ")
	return mcp.NewToolResultText(string(b)), nil
}
