package registry

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

// ToolDef describes a single MCP tool exposed by a skill.
type ToolDef struct {
	Name        string          `json:"name"`
	Description string          `json:"description"`
	InputSchema json.RawMessage `json:"inputSchema"`
}

// Skill is implemented by each skill package (tdd, review, etc.).
type Skill interface {
	Name() string
	Tools() []ToolDef
	Handle(ctx context.Context, tool string, args json.RawMessage) (json.RawMessage, error)
}

// Registry routes MCP tool calls to the correct skill handler.
type Registry struct {
	skills map[string]Skill // tool name → skill
	tools  []ToolDef
}

func New() *Registry {
	return &Registry{
		skills: make(map[string]Skill),
		tools:  make([]ToolDef, 0),
	}
}

func (r *Registry) Register(s Skill) {
	for _, t := range s.Tools() {
		r.skills[t.Name] = s
		r.tools = append(r.tools, t)
	}
}

func (r *Registry) Tools() []ToolDef {
	return r.tools
}

func (r *Registry) Dispatch(ctx context.Context, tool string, args json.RawMessage) (json.RawMessage, error) {
	s, ok := r.skills[tool]
	if !ok {
		return nil, fmt.Errorf("unknown tool: %s", tool)
	}
	return s.Handle(ctx, tool, args)
}
