package tool

import (
	"testing"

	"github.com/kami/maven/internal/ipc"
)

func TestCapabilityOfDescribesTheRow(t *testing.T) {
	cases := []struct {
		name string
		tool ipc.Tool
		want string
	}{
		{
			"a process with a subcommand",
			ipc.Tool{Name: "restart", Scope: "homelab", Cmd: []string{"docker", "restart"}},
			"homelab.docker.restart",
		},
		{
			"a program with a path and a flag",
			ipc.Tool{Name: "backup", Scope: "homelab", Cmd: []string{"/usr/local/bin/borg", "-v"}},
			"homelab.borg.backup",
		},
		{
			"the house",
			ipc.Tool{Name: "unlock_front", Cmd: []string{"smarthome", "lock.front_door", "unlock"}},
			"house.lock.unlock",
		},
		{
			"an mcp tool",
			ipc.Tool{Name: "vikunja_delete_task", Cmd: []string{"mcp", "vikunja", "delete_task"}},
			"mcp_vikunja.vikunja.delete_task",
		},
		{
			"a proposal with no command yet",
			ipc.Tool{Name: "перезапусти", Scope: "homelab"},
			"homelab.unknown.перезапусти",
		},
	}
	for _, c := range cases {
		if got := CapabilityOf(c.tool).String(); got != c.want {
			t.Errorf("%s: %q; want %q", c.name, got, c.want)
		}
	}
}

// A dotted id always has three segments, so a prefix pattern cannot widen by
// accident onto a row whose scope happens to be empty.
func TestCapabilityStringAlwaysHasThreeSegments(t *testing.T) {
	if got := (Capability{}).String(); got != "unknown.unknown.unknown" {
		t.Errorf("empty capability = %q", got)
	}
	if got := (Capability{Scope: "home lab", Domain: "a.b", Action: "X"}).String(); got != "home_lab.a_b.x" {
		t.Errorf("segments not folded: %q", got)
	}
}

func TestMatchCapabilityWidensOneWay(t *testing.T) {
	c := CapabilityOf(ipc.Tool{Name: "unlock_front", Cmd: []string{"smarthome", "lock.front_door", "unlock"}})
	for _, p := range []string{"house", "house.lock", "house.lock.unlock", "house.*.unlock", "*.lock"} {
		if !MatchCapability(p, c) {
			t.Errorf("%q did not match %s", p, c)
		}
	}
	for _, p := range []string{"homelab", "house.light", "house.lock.lock", "house.lock.unlock.now"} {
		if MatchCapability(p, c) {
			t.Errorf("%q matched %s", p, c)
		}
	}
}

func TestGroupByDomainIsStable(t *testing.T) {
	tools := []ipc.Tool{
		{Name: "restart", Scope: "homelab", Cmd: []string{"docker", "restart"}},
		{Name: "unlock_front", Cmd: []string{"smarthome", "lock.front_door", "unlock"}},
		{Name: "logs", Scope: "homelab", Cmd: []string{"docker", "logs"}},
	}
	groups := GroupByDomain(tools)
	if len(groups) != 2 {
		t.Fatalf("%d groups; want 2", len(groups))
	}
	if groups[0].Prefix != "homelab.docker" || len(groups[0].Tools) != 2 {
		t.Errorf("first group %+v; want homelab.docker with 2 rows", groups[0])
	}
	if groups[0].Tools[0].Name != "logs" {
		t.Errorf("rows not sorted: %+v", groups[0].Tools)
	}
	if groups[1].Prefix != "house.lock" {
		t.Errorf("second group %q; want house.lock", groups[1].Prefix)
	}
}
