package main

import (
	"testing"

	"github.com/stretchr/testify/require"
	"gopkg.in/yaml.v3"
)

func TestFindFieldValue(t *testing.T) {
	tests := []struct {
		name        string
		yamlContent string
		fieldName   string
		want        string
	}{
		{
			name: "finds simple string field",
			yamlContent: `
name: test-cataloger
type: custom
`,
			fieldName: "name",
			want:      "test-cataloger",
		},
		{
			name: "finds type field",
			yamlContent: `
name: test-cataloger
type: generic
`,
			fieldName: "type",
			want:      "generic",
		},
		{
			name: "returns empty for non-existent field",
			yamlContent: `
name: test-cataloger
`,
			fieldName: "nonexistent",
			want:      "",
		},
		{
			name: "finds parser_function field",
			yamlContent: `
parser_function: parseGoMod
metadata_types: [GoModMetadata]
`,
			fieldName: "parser_function",
			want:      "parseGoMod",
		},
		{
			name:        "handles empty mapping",
			yamlContent: `{}`,
			fieldName:   "any",
			want:        "",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			var rootNode yaml.Node
			err := yaml.Unmarshal([]byte(tt.yamlContent), &rootNode)
			require.NoError(t, err)

			// get the mapping node
			var mappingNode *yaml.Node
			if rootNode.Kind == yaml.DocumentNode && len(rootNode.Content) > 0 {
				mappingNode = rootNode.Content[0]
			} else {
				mappingNode = &rootNode
			}

			got := findFieldValue(mappingNode, tt.fieldName)
			require.Equal(t, tt.want, got)
		})
	}
}

func TestAddCatalogerFieldComment(t *testing.T) {
	tests := []struct {
		name            string
		fieldName       string
		fieldValue      string
		catalogerName   string
		wantLineComment string
	}{
		{
			name:            "ecosystem is MANUAL",
			fieldName:       "ecosystem",
			catalogerName:   "test-cataloger",
			wantLineComment: "MANUAL",
		},
		{
			name:            "name is AUTO-GENERATED",
			fieldName:       "name",
			catalogerName:   "test-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "type is AUTO-GENERATED",
			fieldName:       "type",
			catalogerName:   "test-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "source is AUTO-GENERATED",
			fieldName:       "source",
			catalogerName:   "test-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "config is AUTO-GENERATED",
			fieldName:       "config",
			catalogerName:   "test-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "selectors is AUTO-GENERATED",
			fieldName:       "selectors",
			catalogerName:   "test-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "parsers is AUTO-GENERATED structure",
			fieldName:       "parsers",
			catalogerName:   "test-cataloger",
			wantLineComment: "AUTO-GENERATED structure",
		},
		{
			name:            "detectors for binary-classifier-cataloger is AUTO-GENERATED",
			fieldName:       "detectors",
			catalogerName:   "binary-classifier-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "detectors for other catalogers is MANUAL",
			fieldName:       "detectors",
			catalogerName:   "java-archive-cataloger",
			wantLineComment: "MANUAL - edit detectors here",
		},
		{
			name:            "metadata_types is AUTO-GENERATED",
			fieldName:       "metadata_types",
			catalogerName:   "test-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "package_types is AUTO-GENERATED",
			fieldName:       "package_types",
			catalogerName:   "test-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "json_schema_types is AUTO-GENERATED",
			fieldName:       "json_schema_types",
			catalogerName:   "test-cataloger",
			wantLineComment: autoGeneratedComment,
		},
		{
			name:            "capabilities is MANUAL",
			fieldName:       "capabilities",
			catalogerName:   "test-cataloger",
			wantLineComment: "MANUAL - edit capabilities here",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// create key and value nodes
			keyNode := &yaml.Node{
				Kind:  yaml.ScalarNode,
				Value: tt.fieldName,
			}
			valueNode := &yaml.Node{
				Kind:  yaml.ScalarNode,
				Value: tt.fieldValue,
			}

			addCatalogerFieldComment(keyNode, valueNode, tt.catalogerName)

			require.Equal(t, tt.wantLineComment, keyNode.LineComment)
		})
	}
}
