package layers

import (
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/kits/agentteam-insight/internal/graphbuilder/schema"
)

// This fixture mechanically adapts the cases in Understand Anything
// packages/core/src/__tests__/layer-detector.test.ts at revision 6ae71878.
func TestGenerateMatchesUpstreamPatternAndOrderingGolden(t *testing.T) {
	graph := schema.KnowledgeGraph{Nodes: []schema.GraphNode{
		{ID: "core:with-path", Type: "file", Name: "main.ts", FilePath: "src/main.ts"},
		{ID: "api:z", Type: "file", Name: "users.ts", FilePath: "src/routes/users.ts"},
		{ID: "core:pathless", Type: "file", Name: "root"},
		{ID: "data:b", Type: "file", Name: "User.ts", FilePath: "src/models/User.ts"},
		{ID: "api:a", Type: "file", Name: "auth.ts", FilePath: "src/controllers/auth.ts"},
		{ID: "fn", Type: "function", Name: "getUser", FilePath: "src/routes/users.ts"},
	}}

	require.Equal(t, []schema.Layer{
		{ID: "layer:core", Name: "Core", Description: "Core application files", NodeIDs: []string{"core:with-path", "core:pathless"}},
		{ID: "layer:api-layer", Name: "API Layer", Description: "HTTP endpoints, route handlers, and API controllers", NodeIDs: []string{"api:z", "api:a"}},
		{ID: "layer:data-layer", Name: "Data Layer", Description: "Data models, database access, and persistence", NodeIDs: []string{"data:b"}},
	}, Generate(graph, Options{}))
}

func TestGeneratePreservesFirstMatchAndPluralSemantics(t *testing.T) {
	graph := schema.KnowledgeGraph{Nodes: []schema.GraphNode{
		{ID: "api-before-data", Type: "file", FilePath: "models/routes/item.ts"},
		{ID: "service-plural", Type: "file", FilePath: "src/services/item.ts"},
		{ID: "windows-api", Type: "file", FilePath: `src\routes\users.ts`},
		{ID: "no-fuzzy-file-match", Type: "file", FilePath: "src/item_test.go"},
	}}
	require.Equal(t, []schema.Layer{
		{ID: "layer:api-layer", Name: "API Layer", Description: "HTTP endpoints, route handlers, and API controllers", NodeIDs: []string{"api-before-data", "windows-api"}},
		{ID: "layer:service-layer", Name: "Service Layer", Description: "Business logic and application services", NodeIDs: []string{"service-plural"}},
		{ID: "layer:core", Name: "Core", Description: "Core application files", NodeIDs: []string{"no-fuzzy-file-match"}},
	}, Generate(graph, Options{}))
}

func TestGenerateAppliesOnlyMechanicalFileLevelAdaptation(t *testing.T) {
	graph := schema.KnowledgeGraph{Nodes: []schema.GraphNode{
		{ID: "document:README.md", Type: "document", FilePath: "README.md"},
		{ID: "endpoint:api", Type: "endpoint", FilePath: "internal/api/handler.go"},
		{ID: "resource:deploy", Type: "resource", FilePath: "deploy/app.yaml"},
		{ID: "service:child", Type: "service", FilePath: "deploy/app.yaml"},
	}, Edges: []schema.GraphEdge{
		{Source: "resource:deploy", Target: "service:child", Type: "contains"},
	}}
	require.Equal(t, []schema.Layer{
		{ID: "layer:core", Name: "Core", Description: "Core application files", NodeIDs: []string{"document:README.md", "resource:deploy"}},
		{ID: "layer:api-layer", Name: "API Layer", Description: "HTTP endpoints, route handlers, and API controllers", NodeIDs: []string{"endpoint:api"}},
	}, Generate(graph, Options{}))
}

func TestGenerateOmitsNonFileLevelNodes(t *testing.T) {
	graph := schema.KnowledgeGraph{Nodes: []schema.GraphNode{{ID: "concept:domain", Type: "concept", Name: "Domain"}}}
	require.Empty(t, Generate(graph, Options{}))
}
