package adk

import (
	"testing"

	"github.com/orchard9/stemedb-go/steme"
)

func TestToolNames(t *testing.T) {
	client := &mockClient{}

	tests := []struct {
		tool         Tool
		expectedName string
	}{
		{NewQueryTool(client), "episteme_query"},
		{NewAssertTool(client), "episteme_assert"},
		{NewConstraintCheckTool(client), "episteme_constraint_check"},
		{NewTraceTool(client), "episteme_trace"},
		{NewSupersedeTool(client), "episteme_supersede"},
	}

	for _, tt := range tests {
		if tt.tool.Name() != tt.expectedName {
			t.Errorf("expected tool name %s, got %s", tt.expectedName, tt.tool.Name())
		}
	}
}

func TestAllTools(t *testing.T) {
	client := &mockClient{}
	tools := AllTools(client)

	if len(tools) != 5 {
		t.Errorf("expected 5 tools, got %d", len(tools))
	}

	// Verify all expected tools are present
	expectedNames := map[string]bool{
		"episteme_query":            false,
		"episteme_assert":           false,
		"episteme_constraint_check": false,
		"episteme_trace":            false,
		"episteme_supersede":        false,
	}

	for _, tool := range tools {
		expectedNames[tool.Name()] = true
	}

	for name, found := range expectedNames {
		if !found {
			t.Errorf("expected to find tool %s", name)
		}
	}
}

func TestConfigCreation(t *testing.T) {
	client := &mockClient{}
	logFunc := func(format string, args ...any) {}
	setState := func(key string, value any) {}

	configs := AllConfigs(client, 0.8, setState, logFunc)

	expectedAgents := []string{
		"implementation",
		"lead",
		"research",
		"supervisor",
		"oncall",
	}

	for _, agentType := range expectedAgents {
		config, ok := configs[agentType]
		if !ok {
			t.Errorf("expected config for %s", agentType)
			continue
		}

		if config.Name == "" {
			t.Errorf("config for %s has empty name", agentType)
		}

		if config.Description == "" {
			t.Errorf("config for %s has empty description", agentType)
		}

		if config.Instruction == "" {
			t.Errorf("config for %s has empty instruction", agentType)
		}

		if len(config.Tools) == 0 {
			t.Errorf("config for %s has no tools", agentType)
		}
	}
}

func TestParseLifecycle(t *testing.T) {
	tests := []struct {
		input    string
		expected steme.LifecycleStage
	}{
		{"proposed", steme.LifecycleProposed},
		{"under_review", steme.LifecycleUnderReview},
		{"approved", steme.LifecycleApproved},
		{"deprecated", steme.LifecycleDeprecated},
		{"rejected", steme.LifecycleRejected},
		{"invalid", steme.LifecycleProposed}, // Default
	}

	for _, tt := range tests {
		result := parseLifecycle(tt.input)
		if result != tt.expected {
			t.Errorf("parseLifecycle(%s) = %v, expected %v", tt.input, result, tt.expected)
		}
	}
}

func TestParseLens(t *testing.T) {
	tests := []struct {
		input    string
		expected steme.Lens
	}{
		{"recency", steme.LensRecency},
		{"consensus", steme.LensConsensus},
		{"authority", steme.LensAuthority},
		{"vote_aware_consensus", steme.LensVoteAwareConsensus},
		{"trust_aware_authority", steme.LensTrustAwareAuthority},
		{"invalid", steme.LensConsensus}, // Default
	}

	for _, tt := range tests {
		result := parseLen(tt.input)
		if result != tt.expected {
			t.Errorf("parseLen(%s) = %v, expected %v", tt.input, result, tt.expected)
		}
	}
}
