package command

import (
	"testing"
)

// NOTE: AI Generated tests

func TestRegistryLookup(t *testing.T) {
	r := NewRegistry()

	t.Run("exact short form match", func(t *testing.T) {
		cmd, err := r.Lookup("q")
		if err != nil {
			t.Fatalf("Lookup error: %v", err)
		}
		if cmd.Name != "quit" {
			t.Errorf("cmd.Name = %q, want \"quit\"", cmd.Name)
		}
	})

	t.Run("exact full name match", func(t *testing.T) {
		cmd, err := r.Lookup("quit")
		if err != nil {
			t.Fatalf("Lookup error: %v", err)
		}
		if cmd.Name != "quit" {
			t.Errorf("cmd.Name = %q, want \"quit\"", cmd.Name)
		}
	})

	t.Run("prefix match", func(t *testing.T) {
		cmd, err := r.Lookup("qui")
		if err != nil {
			t.Fatalf("Lookup error: %v", err)
		}
		if cmd.Name != "quit" {
			t.Errorf("cmd.Name = %q, want \"quit\"", cmd.Name)
		}
	})

	t.Run("qa matches qall not quit", func(t *testing.T) {
		cmd, err := r.Lookup("qa")
		if err != nil {
			t.Fatalf("Lookup error: %v", err)
		}
		if cmd.Name != "qall" {
			t.Errorf("cmd.Name = %q, want \"qall\"", cmd.Name)
		}
	})

	t.Run("qal matches qall", func(t *testing.T) {
		cmd, err := r.Lookup("qal")
		if err != nil {
			t.Fatalf("Lookup error: %v", err)
		}
		if cmd.Name != "qall" {
			t.Errorf("cmd.Name = %q, want \"qall\"", cmd.Name)
		}
	})

	t.Run("w matches write", func(t *testing.T) {
		cmd, err := r.Lookup("w")
		if err != nil {
			t.Fatalf("Lookup error: %v", err)
		}
		if cmd.Name != "write" {
			t.Errorf("cmd.Name = %q, want \"write\"", cmd.Name)
		}
	})

	t.Run("wa matches wall", func(t *testing.T) {
		cmd, err := r.Lookup("wa")
		if err != nil {
			t.Fatalf("Lookup error: %v", err)
		}
		if cmd.Name != "wall" {
			t.Errorf("cmd.Name = %q, want \"wall\"", cmd.Name)
		}
	})

	t.Run("se matches set", func(t *testing.T) {
		cmd, err := r.Lookup("se")
		if err != nil {
			t.Fatalf("Lookup error: %v", err)
		}
		if cmd.Name != "set" {
			t.Errorf("cmd.Name = %q, want \"set\"", cmd.Name)
		}
	})

	t.Run("unknown command returns error", func(t *testing.T) {
		_, err := r.Lookup("xyz")
		if err == nil {
			t.Error("expected error for unknown command")
		}
	})

	t.Run("empty command returns error", func(t *testing.T) {
		_, err := r.Lookup("")
		if err == nil {
			t.Error("expected error for empty command")
		}
	})
}

func TestParse(t *testing.T) {
	t.Run("command only", func(t *testing.T) {
		name, args := Parse("quit")
		if name != "quit" {
			t.Errorf("name = %q, want \"quit\"", name)
		}
		if len(args) != 0 {
			t.Errorf("len(args) = %d, want 0", len(args))
		}
	})

	t.Run("command with one arg", func(t *testing.T) {
		name, args := Parse("set number")
		if name != "set" {
			t.Errorf("name = %q, want \"set\"", name)
		}
		if len(args) != 1 {
			t.Errorf("len(args) = %d, want 1", len(args))
		}
		if args[0] != "number" {
			t.Errorf("args[0] = %q, want \"number\"", args[0])
		}
	})

	t.Run("command with multiple args", func(t *testing.T) {
		name, args := Parse("set number tabstop=4")
		if name != "set" {
			t.Errorf("name = %q, want \"set\"", name)
		}
		if len(args) != 2 {
			t.Errorf("len(args) = %d, want 2", len(args))
		}
		if args[0] != "number" {
			t.Errorf("args[0] = %q, want \"number\"", args[0])
		}
		if args[1] != "tabstop=4" {
			t.Errorf("args[1] = %q, want \"tabstop=4\"", args[1])
		}
	})

	t.Run("empty string", func(t *testing.T) {
		name, args := Parse("")
		if name != "" {
			t.Errorf("name = %q, want \"\"", name)
		}
		if args != nil {
			t.Errorf("args = %v, want nil", args)
		}
	})

	t.Run("whitespace only", func(t *testing.T) {
		name, args := Parse("   ")
		if name != "" {
			t.Errorf("name = %q, want \"\"", name)
		}
		if args != nil {
			t.Errorf("args = %v, want nil", args)
		}
	})
}

func TestLookupSetting(t *testing.T) {
	t.Run("exact name match", func(t *testing.T) {
		s := lookupSetting("number")
		if s == nil {
			t.Fatal("expected setting, got nil")
		}
		if s.Name != "number" {
			t.Errorf("s.Name = %q, want \"number\"", s.Name)
		}
	})

	t.Run("short form match", func(t *testing.T) {
		s := lookupSetting("nu")
		if s == nil {
			t.Fatal("expected setting, got nil")
		}
		if s.Name != "number" {
			t.Errorf("s.Name = %q, want \"number\"", s.Name)
		}
	})

	t.Run("prefix match", func(t *testing.T) {
		s := lookupSetting("numb")
		if s == nil {
			t.Fatal("expected setting, got nil")
		}
		if s.Name != "number" {
			t.Errorf("s.Name = %q, want \"number\"", s.Name)
		}
	})

	t.Run("rnu matches relativenumber", func(t *testing.T) {
		s := lookupSetting("rnu")
		if s == nil {
			t.Fatal("expected setting, got nil")
		}
		if s.Name != "relativenumber" {
			t.Errorf("s.Name = %q, want \"relativenumber\"", s.Name)
		}
	})

	t.Run("ts matches tabstop", func(t *testing.T) {
		s := lookupSetting("ts")
		if s == nil {
			t.Fatal("expected setting, got nil")
		}
		if s.Name != "tabstop" {
			t.Errorf("s.Name = %q, want \"tabstop\"", s.Name)
		}
	})

	t.Run("so matches scrolloff", func(t *testing.T) {
		s := lookupSetting("so")
		if s == nil {
			t.Fatal("expected setting, got nil")
		}
		if s.Name != "scrolloff" {
			t.Errorf("s.Name = %q, want \"scrolloff\"", s.Name)
		}
	})

	t.Run("unknown returns nil", func(t *testing.T) {
		s := lookupSetting("xyz")
		if s != nil {
			t.Errorf("expected nil, got %v", s)
		}
	})
}
