package main

import (
	"context"
	"encoding/json"

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

type usesArgs struct {
	ID string `json:"id"`
}

func usesTool() mcp.Tool {
	return mcp.NewTool("fn_uses",
		mcp.WithDescription("Return the dependency edges for a function or type: which functions/types it uses (forward) and which functions consume it (reverse). Reverse lookup uses LIKE on uses_functions/uses_types JSON, so it's O(N) over the table — fast on registry.db (~1k rows)."),
		mcp.WithString("id",
			mcp.Required(),
			mcp.Description("Registry ID."),
		),
	)
}

func (d *deps) handleUses(ctx context.Context, _ mcp.CallToolRequest, args usesArgs) (*mcp.CallToolResult, error) {
	if args.ID == "" {
		return mcp.NewToolResultError("id is required"), nil
	}

	out := map[string]any{"id": args.ID}
	if f, err := d.db.GetFunction(args.ID); err == nil {
		out["entity"] = "function"
		out["uses_functions"] = f.UsesFunctions
		out["uses_types"] = f.UsesTypes
	} else if t, err := d.db.GetType(args.ID); err == nil {
		out["entity"] = "type"
		out["uses_types"] = t.UsesTypes
	} else {
		return mcp.NewToolResultError("id not found: " + args.ID), nil
	}

	conn := d.db.Conn()
	pattern := "%\"" + args.ID + "\"%"
	rows, err := conn.Query(`SELECT id FROM functions WHERE uses_functions LIKE ? OR uses_types LIKE ? ORDER BY id`, pattern, pattern)
	if err != nil {
		return mcp.NewToolResultError("reverse lookup: " + err.Error()), nil
	}
	defer rows.Close()
	var consumers []string
	for rows.Next() {
		var id string
		if err := rows.Scan(&id); err != nil {
			return mcp.NewToolResultError("scan reverse: " + err.Error()), nil
		}
		consumers = append(consumers, id)
	}
	out["consumed_by"] = consumers

	// Apps that declare the id in uses_functions (the apps table also stores the JSON list).
	rows, err = conn.Query(`SELECT id FROM apps WHERE uses_functions LIKE ? ORDER BY id`, pattern)
	if err == nil {
		defer rows.Close()
		var apps []string
		for rows.Next() {
			var id string
			if err := rows.Scan(&id); err == nil {
				apps = append(apps, id)
			}
		}
		out["consumed_by_apps"] = apps
	}

	b, _ := json.MarshalIndent(out, "", "  ")
	return mcp.NewToolResultText(string(b)), nil
}
