package file

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/traefik/paerser/parser"
)

func Test_getRootFieldNames(t *testing.T) {
	testCases := []struct {
		desc     string
		element  interface{}
		expected []string
	}{
		{
			desc:     "simple fields",
			element:  &Yo{},
			expected: []string{"Foo", "Fii", "Fuu", "Yi"},
		},
		{
			desc:     "embedded struct",
			element:  &Yu{},
			expected: []string{"Foo", "Fii", "Fuu"},
		},
		{
			desc:     "embedded struct pointer",
			element:  &Ye{},
			expected: []string{"Foo", "Fii", "Fuu"},
		},
	}

	for _, test := range testCases {
		test := test
		t.Run(test.desc, func(t *testing.T) {
			t.Parallel()

			names := getRootFieldNames(test.element)

			assert.Equal(t, test.expected, names)
		})
	}
}

func Test_decodeFileToNode_errors(t *testing.T) {
	testCases := []struct {
		desc     string
		confFile string
	}{
		{
			desc:     "non existing file",
			confFile: "./fixtures/not_existing.toml",
		},
		{
			desc:     "file without content",
			confFile: "./fixtures/empty.toml",
		},
		{
			desc:     "file without any valid configuration",
			confFile: "./fixtures/no_conf.toml",
		},
	}

	for _, test := range testCases {
		t.Run(test.desc, func(t *testing.T) {
			node, err := decodeFileToNode(test.confFile,
				"Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "CertificatesResolvers")

			require.Error(t, err)
			assert.Nil(t, node)
		})
	}
}

func Test_decodeFileToNode_compare(t *testing.T) {
	nodeToml, err := decodeFileToNode("./fixtures/sample.toml",
		"Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "CertificatesResolvers")
	require.NoError(t, err)

	nodeYaml, err := decodeFileToNode("./fixtures/sample.yml")
	require.NoError(t, err)

	assert.Equal(t, nodeToml, nodeYaml)
}

func Test_decodeFileToNode_Toml(t *testing.T) {
	node, err := decodeFileToNode("./fixtures/sample.toml",
		"Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "CertificatesResolvers")
	require.NoError(t, err)

	expected := &parser.Node{
		Name: "traefik",
		Children: []*parser.Node{
			{Name: "accessLog", Children: []*parser.Node{
				{Name: "bufferingSize", Value: "42"},
				{Name: "fields", Children: []*parser.Node{
					{Name: "defaultMode", Value: "foobar"},
					{Name: "headers", Children: []*parser.Node{
						{Name: "defaultMode", Value: "foobar"},
						{Name: "names", Children: []*parser.Node{
							{Name: "name0", Value: "foobar"},
							{Name: "name1", Value: "foobar"},
						}},
					}},
					{Name: "names", Children: []*parser.Node{
						{Name: "name0", Value: "foobar"},
						{Name: "name1", Value: "foobar"},
					}},
				}},
				{Name: "filePath", Value: "foobar"},
				{Name: "filters", Children: []*parser.Node{
					{Name: "minDuration", Value: "42"},
					{Name: "retryAttempts", Value: "true"},
					{Name: "statusCodes", Value: "║24║foobar║foobar"},
				}},
				{Name: "format", Value: "foobar"},
			}},
			{Name: "api", Children: []*parser.Node{
				{Name: "dashboard", Value: "true"},
				{Name: "entryPoint", Value: "foobar"},
				{Name: "middlewares", Value: "║24║foobar║foobar"},
				{Name: "statistics", Children: []*parser.Node{
					{Name: "recentErrors", Value: "42"},
				}},
			}},
			{Name: "certificatesResolvers", Children: []*parser.Node{
				{Name: "default", Children: []*parser.Node{
					{
						Name: "acme",
						Children: []*parser.Node{
							{Name: "acmeLogging", Value: "true"},
							{Name: "caServer", Value: "foobar"},
							{Name: "dnsChallenge", Children: []*parser.Node{
								{Name: "delayBeforeCheck", Value: "42"},
								{Name: "disablePropagationCheck", Value: "true"},
								{Name: "provider", Value: "foobar"},
								{Name: "resolvers", Value: "║24║foobar║foobar"},
							}},
							{Name: "email", Value: "foobar"},
							{Name: "entryPoint", Value: "foobar"},
							{Name: "httpChallenge", Children: []*parser.Node{
								{Name: "entryPoint", Value: "foobar"},
							}},
							{Name: "keyType", Value: "foobar"},
							{Name: "storage", Value: "foobar"},
							{Name: "tlsChallenge"},
						},
					},
				}},
			}},
			{Name: "entryPoints", Children: []*parser.Node{
				{Name: "EntryPoint0", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "forwardedHeaders", Children: []*parser.Node{
						{Name: "insecure", Value: "true"},
						{Name: "trustedIPs", Value: "║24║foobar║foobar"},
					}},
					{Name: "proxyProtocol", Children: []*parser.Node{
						{Name: "insecure", Value: "true"},
						{Name: "trustedIPs", Value: "║24║foobar║foobar"},
					}},
					{Name: "transport", Children: []*parser.Node{
						{Name: "lifeCycle", Children: []*parser.Node{
							{Name: "graceTimeOut", Value: "42"},
							{Name: "requestAcceptGraceTimeout", Value: "42"},
						}},
						{Name: "respondingTimeouts", Children: []*parser.Node{
							{Name: "idleTimeout", Value: "42"},
							{Name: "readTimeout", Value: "42"},
							{Name: "writeTimeout", Value: "42"},
						}},
					}},
				}},
			}},
			{Name: "global", Children: []*parser.Node{
				{Name: "checkNewVersion", Value: "true"},
				{Name: "sendAnonymousUsage", Value: "true"},
			}},
			{Name: "hostResolver", Children: []*parser.Node{
				{Name: "cnameFlattening", Value: "true"},
				{Name: "resolvConfig", Value: "foobar"},
				{Name: "resolvDepth", Value: "42"},
			}},
			{Name: "log", Children: []*parser.Node{
				{Name: "filePath", Value: "foobar"},
				{Name: "format", Value: "foobar"},
				{Name: "level", Value: "foobar"},
			}},
			{Name: "metrics", Children: []*parser.Node{
				{Name: "datadog", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
				}},
				{Name: "influxDB", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "database", Value: "foobar"},
					{Name: "password", Value: "foobar"},
					{Name: "protocol", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
					{Name: "retentionPolicy", Value: "foobar"},
					{Name: "username", Value: "foobar"},
				}},
				{Name: "prometheus", Children: []*parser.Node{
					{Name: "buckets", Value: "║14║42.010000║42.020000"},
					{Name: "entryPoint", Value: "foobar"},
					{Name: "middlewares", Value: "║24║foobar║foobar"},
				}},
				{Name: "statsD", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
				}},
			}},
			{Name: "ping", Children: []*parser.Node{
				{Name: "entryPoint", Value: "foobar"},
				{Name: "middlewares", Value: "║24║foobar║foobar"},
			}},
			{Name: "providers", Children: []*parser.Node{
				{Name: "docker", Children: []*parser.Node{
					{Name: "constraints", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "network", Value: "foobar"},
					{Name: "swarmMode", Value: "true"},
					{Name: "swarmModeRefreshSeconds", Value: "42"},
					{Name: "tls", Children: []*parser.Node{
						{Name: "ca", Value: "foobar"},
						{Name: "caOptional", Value: "true"},
						{Name: "cert", Value: "foobar"},
						{Name: "insecureSkipVerify", Value: "true"},
						{Name: "key", Value: "foobar"},
					}},
					{Name: "useBindPortIP", Value: "true"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "file", Children: []*parser.Node{
					{Name: "debugLogGeneratedTemplate", Value: "true"},
					{Name: "directory", Value: "foobar"},
					{Name: "filename", Value: "foobar"},
					{Name: "watch", Value: "true"},
				}},
				{
					Name: "kubernetesCRD",
					Children: []*parser.Node{
						{Name: "certAuthFilePath", Value: "foobar"},
						{Name: "disablePassHostHeaders", Value: "true"},
						{Name: "endpoint", Value: "foobar"},
						{Name: "ingressClass", Value: "foobar"},
						{Name: "labelSelector", Value: "foobar"},
						{Name: "namespaces", Value: "║24║foobar║foobar"},
						{Name: "token", Value: "foobar"},
					},
				},
				{Name: "kubernetesIngress", Children: []*parser.Node{
					{Name: "certAuthFilePath", Value: "foobar"},
					{Name: "disablePassHostHeaders", Value: "true"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "ingressClass", Value: "foobar"},
					{Name: "ingressEndpoint", Children: []*parser.Node{
						{Name: "hostname", Value: "foobar"},
						{Name: "ip", Value: "foobar"},
						{Name: "publishedService", Value: "foobar"},
					}},
					{Name: "labelSelector", Value: "foobar"},
					{Name: "namespaces", Value: "║24║foobar║foobar"},
					{Name: "token", Value: "foobar"},
				}},
				{Name: "marathon", Children: []*parser.Node{
					{Name: "basic", Children: []*parser.Node{
						{Name: "httpBasicAuthUser", Value: "foobar"},
						{Name: "httpBasicPassword", Value: "foobar"},
					}},
					{Name: "constraints", Value: "foobar"},
					{Name: "dcosToken", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "dialerTimeout", Value: "42"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "forceTaskHostname", Value: "true"},
					{Name: "keepAlive", Value: "42"},
					{Name: "respectReadinessChecks", Value: "true"},
					{Name: "responseHeaderTimeout", Value: "42"},
					{Name: "tls", Children: []*parser.Node{
						{Name: "ca", Value: "foobar"},
						{Name: "caOptional", Value: "true"},
						{Name: "cert", Value: "foobar"},
						{Name: "insecureSkipVerify", Value: "true"},
						{Name: "key", Value: "foobar"},
					}},
					{Name: "tlsHandshakeTimeout", Value: "42"},
					{Name: "trace", Value: "true"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "providersThrottleDuration", Value: "42"},
				{Name: "rancher", Children: []*parser.Node{
					{Name: "constraints", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "enableServiceHealthFilter", Value: "true"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "intervalPoll", Value: "true"},
					{Name: "prefix", Value: "foobar"},
					{Name: "refreshSeconds", Value: "42"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "rest", Children: []*parser.Node{
					{Name: "entryPoint", Value: "foobar"},
				}},
			}},
			{Name: "serversTransport", Children: []*parser.Node{
				{Name: "forwardingTimeouts", Children: []*parser.Node{
					{Name: "dialTimeout", Value: "42"},
					{Name: "idleConnTimeout", Value: "42"},
					{Name: "responseHeaderTimeout", Value: "42"},
				}},
				{Name: "insecureSkipVerify", Value: "true"},
				{Name: "maxIdleConnsPerHost", Value: "42"},
				{Name: "rootCAs", Value: "║24║foobar║foobar"},
			}},
			{Name: "tracing", Children: []*parser.Node{
				{Name: "datadog", Children: []*parser.Node{
					{Name: "bagagePrefixHeaderName", Value: "foobar"},
					{Name: "debug", Value: "true"},
					{Name: "globalTag", Value: "foobar"},
					{Name: "localAgentHostPort", Value: "foobar"},
					{Name: "parentIDHeaderName", Value: "foobar"},
					{Name: "prioritySampling", Value: "true"},
					{Name: "samplingPriorityHeaderName", Value: "foobar"},
					{Name: "traceIDHeaderName", Value: "foobar"},
				}},
				{Name: "haystack", Children: []*parser.Node{
					{Name: "globalTag", Value: "foobar"},
					{Name: "localAgentHost", Value: "foobar"},
					{Name: "localAgentPort", Value: "42"},
					{Name: "parentIDHeaderName", Value: "foobar"},
					{Name: "spanIDHeaderName", Value: "foobar"},
					{Name: "traceIDHeaderName", Value: "foobar"},
				}},
				{Name: "instana", Children: []*parser.Node{
					{Name: "localAgentHost", Value: "foobar"},
					{Name: "localAgentPort", Value: "42"},
					{Name: "logLevel", Value: "foobar"},
				}},
				{Name: "jaeger", Children: []*parser.Node{
					{Name: "gen128Bit", Value: "true"},
					{Name: "localAgentHostPort", Value: "foobar"},
					{Name: "propagation", Value: "foobar"},
					{Name: "samplingParam", Value: "42"},
					{Name: "samplingServerURL", Value: "foobar"},
					{Name: "samplingType", Value: "foobar"},
					{Name: "traceContextHeaderName", Value: "foobar"},
				}},
				{Name: "serviceName", Value: "foobar"},
				{Name: "spanNameLimit", Value: "42"},
				{Name: "zipkin", Children: []*parser.Node{
					{Name: "httpEndpoint", Value: "foobar"},
					{Name: "id128Bit", Value: "true"},
					{Name: "sameSpan", Value: "true"},
					{Name: "sampleRate", Value: "42"},
				}},
			}},
		},
	}

	assert.Equal(t, expected, node)
}

func Test_decodeFileToNode_Yaml(t *testing.T) {
	node, err := decodeFileToNode("./fixtures/sample.yml")
	require.NoError(t, err)

	expected := &parser.Node{
		Name: "traefik",
		Children: []*parser.Node{
			{Name: "accessLog", Children: []*parser.Node{
				{Name: "bufferingSize", Value: "42"},
				{Name: "fields", Children: []*parser.Node{
					{Name: "defaultMode", Value: "foobar"},
					{Name: "headers", Children: []*parser.Node{
						{Name: "defaultMode", Value: "foobar"},
						{Name: "names", Children: []*parser.Node{
							{Name: "name0", Value: "foobar"},
							{Name: "name1", Value: "foobar"},
						}},
					}},
					{Name: "names", Children: []*parser.Node{
						{Name: "name0", Value: "foobar"},
						{Name: "name1", Value: "foobar"},
					}},
				}},
				{Name: "filePath", Value: "foobar"},
				{Name: "filters", Children: []*parser.Node{
					{Name: "minDuration", Value: "42"},
					{Name: "retryAttempts", Value: "true"},
					{Name: "statusCodes", Value: "║24║foobar║foobar"},
				}},
				{Name: "format", Value: "foobar"},
			}},
			{Name: "api", Children: []*parser.Node{
				{Name: "dashboard", Value: "true"},
				{Name: "entryPoint", Value: "foobar"},
				{Name: "middlewares", Value: "║24║foobar║foobar"},
				{Name: "statistics", Children: []*parser.Node{
					{Name: "recentErrors", Value: "42"},
				}},
			}},
			{Name: "certificatesResolvers", Children: []*parser.Node{
				{Name: "default", Children: []*parser.Node{
					{
						Name: "acme",
						Children: []*parser.Node{
							{Name: "acmeLogging", Value: "true"},
							{Name: "caServer", Value: "foobar"},
							{Name: "dnsChallenge", Children: []*parser.Node{
								{Name: "delayBeforeCheck", Value: "42"},
								{Name: "disablePropagationCheck", Value: "true"},
								{Name: "provider", Value: "foobar"},
								{Name: "resolvers", Value: "║24║foobar║foobar"},
							}},
							{Name: "email", Value: "foobar"},
							{Name: "entryPoint", Value: "foobar"},
							{Name: "httpChallenge", Children: []*parser.Node{
								{Name: "entryPoint", Value: "foobar"},
							}},
							{Name: "keyType", Value: "foobar"},
							{Name: "storage", Value: "foobar"},
							{Name: "tlsChallenge"},
						},
					},
				}},
			}},
			{Name: "entryPoints", Children: []*parser.Node{
				{Name: "EntryPoint0", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "forwardedHeaders", Children: []*parser.Node{
						{Name: "insecure", Value: "true"},
						{Name: "trustedIPs", Value: "║24║foobar║foobar"},
					}},
					{Name: "proxyProtocol", Children: []*parser.Node{
						{Name: "insecure", Value: "true"},
						{Name: "trustedIPs", Value: "║24║foobar║foobar"},
					}},
					{Name: "transport", Children: []*parser.Node{
						{Name: "lifeCycle", Children: []*parser.Node{
							{Name: "graceTimeOut", Value: "42"},
							{Name: "requestAcceptGraceTimeout", Value: "42"},
						}},
						{Name: "respondingTimeouts", Children: []*parser.Node{
							{Name: "idleTimeout", Value: "42"},
							{Name: "readTimeout", Value: "42"},
							{Name: "writeTimeout", Value: "42"},
						}},
					}},
				}},
			}},
			{Name: "global", Children: []*parser.Node{
				{Name: "checkNewVersion", Value: "true"},
				{Name: "sendAnonymousUsage", Value: "true"},
			}},
			{Name: "hostResolver", Children: []*parser.Node{
				{Name: "cnameFlattening", Value: "true"},
				{Name: "resolvConfig", Value: "foobar"},
				{Name: "resolvDepth", Value: "42"},
			}},
			{Name: "log", Children: []*parser.Node{
				{Name: "filePath", Value: "foobar"},
				{Name: "format", Value: "foobar"},
				{Name: "level", Value: "foobar"},
			}},
			{Name: "metrics", Children: []*parser.Node{
				{Name: "datadog", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
				}},
				{Name: "influxDB", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "database", Value: "foobar"},
					{Name: "password", Value: "foobar"},
					{Name: "protocol", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
					{Name: "retentionPolicy", Value: "foobar"},
					{Name: "username", Value: "foobar"},
				}},
				{Name: "prometheus", Children: []*parser.Node{
					{Name: "buckets", Value: "║14║42.010000║42.020000"},
					{Name: "entryPoint", Value: "foobar"},
					{Name: "middlewares", Value: "║24║foobar║foobar"},
				}},
				{Name: "statsD", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
				}},
			}},
			{Name: "ping", Children: []*parser.Node{
				{Name: "entryPoint", Value: "foobar"},
				{Name: "middlewares", Value: "║24║foobar║foobar"},
			}},
			{Name: "providers", Children: []*parser.Node{
				{Name: "docker", Children: []*parser.Node{
					{Name: "constraints", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "network", Value: "foobar"},
					{Name: "swarmMode", Value: "true"},
					{Name: "swarmModeRefreshSeconds", Value: "42"},
					{Name: "tls", Children: []*parser.Node{
						{Name: "ca", Value: "foobar"},
						{Name: "caOptional", Value: "true"},
						{Name: "cert", Value: "foobar"},
						{Name: "insecureSkipVerify", Value: "true"},
						{Name: "key", Value: "foobar"},
					}},
					{Name: "useBindPortIP", Value: "true"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "file", Children: []*parser.Node{
					{Name: "debugLogGeneratedTemplate", Value: "true"},
					{Name: "directory", Value: "foobar"},
					{Name: "filename", Value: "foobar"},
					{Name: "watch", Value: "true"},
				}},
				{
					Name: "kubernetesCRD",
					Children: []*parser.Node{
						{Name: "certAuthFilePath", Value: "foobar"},
						{Name: "disablePassHostHeaders", Value: "true"},
						{Name: "endpoint", Value: "foobar"},
						{Name: "ingressClass", Value: "foobar"},
						{Name: "labelSelector", Value: "foobar"},
						{Name: "namespaces", Value: "║24║foobar║foobar"},
						{Name: "token", Value: "foobar"},
					},
				},
				{Name: "kubernetesIngress", Children: []*parser.Node{
					{Name: "certAuthFilePath", Value: "foobar"},
					{Name: "disablePassHostHeaders", Value: "true"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "ingressClass", Value: "foobar"},
					{Name: "ingressEndpoint", Children: []*parser.Node{
						{Name: "hostname", Value: "foobar"},
						{Name: "ip", Value: "foobar"},
						{Name: "publishedService", Value: "foobar"},
					}},
					{Name: "labelSelector", Value: "foobar"},
					{Name: "namespaces", Value: "║24║foobar║foobar"},
					{Name: "token", Value: "foobar"},
				}},
				{Name: "marathon", Children: []*parser.Node{
					{Name: "basic", Children: []*parser.Node{
						{Name: "httpBasicAuthUser", Value: "foobar"},
						{Name: "httpBasicPassword", Value: "foobar"},
					}},
					{Name: "constraints", Value: "foobar"},
					{Name: "dcosToken", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "dialerTimeout", Value: "42"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "forceTaskHostname", Value: "true"},
					{Name: "keepAlive", Value: "42"},
					{Name: "respectReadinessChecks", Value: "true"},
					{Name: "responseHeaderTimeout", Value: "42"},
					{Name: "tls", Children: []*parser.Node{
						{Name: "ca", Value: "foobar"},
						{Name: "caOptional", Value: "true"},
						{Name: "cert", Value: "foobar"},
						{Name: "insecureSkipVerify", Value: "true"},
						{Name: "key", Value: "foobar"},
					}},
					{Name: "tlsHandshakeTimeout", Value: "42"},
					{Name: "trace", Value: "true"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "providersThrottleDuration", Value: "42"},
				{Name: "rancher", Children: []*parser.Node{
					{Name: "constraints", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "enableServiceHealthFilter", Value: "true"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "intervalPoll", Value: "true"},
					{Name: "prefix", Value: "foobar"},
					{Name: "refreshSeconds", Value: "42"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "rest", Children: []*parser.Node{
					{Name: "entryPoint", Value: "foobar"},
				}},
			}},
			{Name: "serversTransport", Children: []*parser.Node{
				{Name: "forwardingTimeouts", Children: []*parser.Node{
					{Name: "dialTimeout", Value: "42"},
					{Name: "idleConnTimeout", Value: "42"},
					{Name: "responseHeaderTimeout", Value: "42"},
				}},
				{Name: "insecureSkipVerify", Value: "true"},
				{Name: "maxIdleConnsPerHost", Value: "42"},
				{Name: "rootCAs", Value: "║24║foobar║foobar"},
			}},
			{Name: "tracing", Children: []*parser.Node{
				{Name: "datadog", Children: []*parser.Node{
					{Name: "bagagePrefixHeaderName", Value: "foobar"},
					{Name: "debug", Value: "true"},
					{Name: "globalTag", Value: "foobar"},
					{Name: "localAgentHostPort", Value: "foobar"},
					{Name: "parentIDHeaderName", Value: "foobar"},
					{Name: "prioritySampling", Value: "true"},
					{Name: "samplingPriorityHeaderName", Value: "foobar"},
					{Name: "traceIDHeaderName", Value: "foobar"},
				}},
				{Name: "haystack", Children: []*parser.Node{
					{Name: "globalTag", Value: "foobar"},
					{Name: "localAgentHost", Value: "foobar"},
					{Name: "localAgentPort", Value: "42"},
					{Name: "parentIDHeaderName", Value: "foobar"},
					{Name: "spanIDHeaderName", Value: "foobar"},
					{Name: "traceIDHeaderName", Value: "foobar"},
				}},
				{Name: "instana", Children: []*parser.Node{
					{Name: "localAgentHost", Value: "foobar"},
					{Name: "localAgentPort", Value: "42"},
					{Name: "logLevel", Value: "foobar"},
				}},
				{Name: "jaeger", Children: []*parser.Node{
					{Name: "gen128Bit", Value: "true"},
					{Name: "localAgentHostPort", Value: "foobar"},
					{Name: "propagation", Value: "foobar"},
					{Name: "samplingParam", Value: "42"},
					{Name: "samplingServerURL", Value: "foobar"},
					{Name: "samplingType", Value: "foobar"},
					{Name: "traceContextHeaderName", Value: "foobar"},
				}},
				{Name: "serviceName", Value: "foobar"},
				{Name: "spanNameLimit", Value: "42"},
				{Name: "zipkin", Children: []*parser.Node{
					{Name: "httpEndpoint", Value: "foobar"},
					{Name: "id128Bit", Value: "true"},
					{Name: "sameSpan", Value: "true"},
					{Name: "sampleRate", Value: "42"},
				}},
			}},
		},
	}

	assert.Equal(t, expected, node)
}

func Test_decodeFileToNode_Json(t *testing.T) {
	node, err := decodeFileToNode("./fixtures/sample.json")
	require.NoError(t, err)

	expected := &parser.Node{
		Name: "traefik",
		Children: []*parser.Node{
			{Name: "accessLog", Children: []*parser.Node{
				{Name: "bufferingSize", Value: "42"},
				{Name: "fields", Children: []*parser.Node{
					{Name: "defaultMode", Value: "foobar"},
					{Name: "headers", Children: []*parser.Node{
						{Name: "defaultMode", Value: "foobar"},
						{Name: "names", Children: []*parser.Node{
							{Name: "name0", Value: "foobar"},
							{Name: "name1", Value: "foobar"},
						}},
					}},
					{Name: "names", Children: []*parser.Node{
						{Name: "name0", Value: "foobar"},
						{Name: "name1", Value: "foobar"},
					}},
				}},
				{Name: "filePath", Value: "foobar"},
				{Name: "filters", Children: []*parser.Node{
					{Name: "minDuration", Value: "42"},
					{Name: "retryAttempts", Value: "true"},
					{Name: "statusCodes", Value: "║24║foobar║foobar"},
				}},
				{Name: "format", Value: "foobar"},
			}},
			{Name: "api", Children: []*parser.Node{
				{Name: "dashboard", Value: "true"},
				{Name: "entryPoint", Value: "foobar"},
				{Name: "middlewares", Value: "║24║foobar║foobar"},
				{Name: "statistics", Children: []*parser.Node{
					{Name: "recentErrors", Value: "42"},
				}},
			}},
			{Name: "certificatesResolvers", Children: []*parser.Node{
				{Name: "default", Children: []*parser.Node{
					{
						Name: "acme",
						Children: []*parser.Node{
							{Name: "acmeLogging", Value: "true"},
							{Name: "caServer", Value: "foobar"},
							{Name: "dnsChallenge", Children: []*parser.Node{
								{Name: "delayBeforeCheck", Value: "42"},
								{Name: "disablePropagationCheck", Value: "true"},
								{Name: "provider", Value: "foobar"},
								{Name: "resolvers", Value: "║24║foobar║foobar"},
							}},
							{Name: "email", Value: "foobar"},
							{Name: "entryPoint", Value: "foobar"},
							{Name: "httpChallenge", Children: []*parser.Node{
								{Name: "entryPoint", Value: "foobar"},
							}},
							{Name: "keyType", Value: "foobar"},
							{Name: "storage", Value: "foobar"},
							{Name: "tlsChallenge"},
						},
					},
				}},
			}},
			{Name: "entryPoints", Children: []*parser.Node{
				{Name: "EntryPoint0", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "forwardedHeaders", Children: []*parser.Node{
						{Name: "insecure", Value: "true"},
						{Name: "trustedIPs", Value: "║24║foobar║foobar"},
					}},
					{Name: "proxyProtocol", Children: []*parser.Node{
						{Name: "insecure", Value: "true"},
						{Name: "trustedIPs", Value: "║24║foobar║foobar"},
					}},
					{Name: "transport", Children: []*parser.Node{
						{Name: "lifeCycle", Children: []*parser.Node{
							{Name: "graceTimeOut", Value: "42"},
							{Name: "requestAcceptGraceTimeout", Value: "42"},
						}},
						{Name: "respondingTimeouts", Children: []*parser.Node{
							{Name: "idleTimeout", Value: "42"},
							{Name: "readTimeout", Value: "42"},
							{Name: "writeTimeout", Value: "42"},
						}},
					}},
				}},
			}},
			{Name: "global", Children: []*parser.Node{
				{Name: "checkNewVersion", Value: "true"},
				{Name: "sendAnonymousUsage", Value: "true"},
			}},
			{Name: "hostResolver", Children: []*parser.Node{
				{Name: "cnameFlattening", Value: "true"},
				{Name: "resolvConfig", Value: "foobar"},
				{Name: "resolvDepth", Value: "42"},
			}},
			{Name: "log", Children: []*parser.Node{
				{Name: "filePath", Value: "foobar"},
				{Name: "format", Value: "foobar"},
				{Name: "level", Value: "foobar"},
			}},
			{Name: "metrics", Children: []*parser.Node{
				{Name: "datadog", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
				}},
				{Name: "influxDB", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "database", Value: "foobar"},
					{Name: "password", Value: "foobar"},
					{Name: "protocol", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
					{Name: "retentionPolicy", Value: "foobar"},
					{Name: "username", Value: "foobar"},
				}},
				{Name: "prometheus", Children: []*parser.Node{
					{Name: "buckets", Value: "║14║42.010000║42.020000"},
					{Name: "entryPoint", Value: "foobar"},
					{Name: "middlewares", Value: "║24║foobar║foobar"},
				}},
				{Name: "statsD", Children: []*parser.Node{
					{Name: "address", Value: "foobar"},
					{Name: "pushInterval", Value: "10s"},
				}},
			}},
			{Name: "ping", Children: []*parser.Node{
				{Name: "entryPoint", Value: "foobar"},
				{Name: "middlewares", Value: "║24║foobar║foobar"},
			}},
			{Name: "providers", Children: []*parser.Node{
				{Name: "docker", Children: []*parser.Node{
					{Name: "constraints", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "network", Value: "foobar"},
					{Name: "swarmMode", Value: "true"},
					{Name: "swarmModeRefreshSeconds", Value: "42"},
					{Name: "tls", Children: []*parser.Node{
						{Name: "ca", Value: "foobar"},
						{Name: "caOptional", Value: "true"},
						{Name: "cert", Value: "foobar"},
						{Name: "insecureSkipVerify", Value: "true"},
						{Name: "key", Value: "foobar"},
					}},
					{Name: "useBindPortIP", Value: "true"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "file", Children: []*parser.Node{
					{Name: "debugLogGeneratedTemplate", Value: "true"},
					{Name: "directory", Value: "foobar"},
					{Name: "filename", Value: "foobar"},
					{Name: "watch", Value: "true"},
				}},
				{
					Name: "kubernetesCRD",
					Children: []*parser.Node{
						{Name: "certAuthFilePath", Value: "foobar"},
						{Name: "disablePassHostHeaders", Value: "true"},
						{Name: "endpoint", Value: "foobar"},
						{Name: "ingressClass", Value: "foobar"},
						{Name: "labelSelector", Value: "foobar"},
						{Name: "namespaces", Value: "║24║foobar║foobar"},
						{Name: "token", Value: "foobar"},
					},
				},
				{Name: "kubernetesIngress", Children: []*parser.Node{
					{Name: "certAuthFilePath", Value: "foobar"},
					{Name: "disablePassHostHeaders", Value: "true"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "ingressClass", Value: "foobar"},
					{Name: "ingressEndpoint", Children: []*parser.Node{
						{Name: "hostname", Value: "foobar"},
						{Name: "ip", Value: "foobar"},
						{Name: "publishedService", Value: "foobar"},
					}},
					{Name: "labelSelector", Value: "foobar"},
					{Name: "namespaces", Value: "║24║foobar║foobar"},
					{Name: "token", Value: "foobar"},
				}},
				{Name: "marathon", Children: []*parser.Node{
					{Name: "basic", Children: []*parser.Node{
						{Name: "httpBasicAuthUser", Value: "foobar"},
						{Name: "httpBasicPassword", Value: "foobar"},
					}},
					{Name: "constraints", Value: "foobar"},
					{Name: "dcosToken", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "dialerTimeout", Value: "42"},
					{Name: "endpoint", Value: "foobar"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "forceTaskHostname", Value: "true"},
					{Name: "keepAlive", Value: "42"},
					{Name: "respectReadinessChecks", Value: "true"},
					{Name: "responseHeaderTimeout", Value: "42"},
					{Name: "tls", Children: []*parser.Node{
						{Name: "ca", Value: "foobar"},
						{Name: "caOptional", Value: "true"},
						{Name: "cert", Value: "foobar"},
						{Name: "insecureSkipVerify", Value: "true"},
						{Name: "key", Value: "foobar"},
					}},
					{Name: "tlsHandshakeTimeout", Value: "42"},
					{Name: "trace", Value: "true"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "providersThrottleDuration", Value: "42"},
				{Name: "rancher", Children: []*parser.Node{
					{Name: "constraints", Value: "foobar"},
					{Name: "defaultRule", Value: "foobar"},
					{Name: "enableServiceHealthFilter", Value: "true"},
					{Name: "exposedByDefault", Value: "true"},
					{Name: "intervalPoll", Value: "true"},
					{Name: "prefix", Value: "foobar"},
					{Name: "refreshSeconds", Value: "42"},
					{Name: "watch", Value: "true"},
				}},
				{Name: "rest", Children: []*parser.Node{
					{Name: "entryPoint", Value: "foobar"},
				}},
			}},
			{Name: "serversTransport", Children: []*parser.Node{
				{Name: "forwardingTimeouts", Children: []*parser.Node{
					{Name: "dialTimeout", Value: "42"},
					{Name: "idleConnTimeout", Value: "42"},
					{Name: "responseHeaderTimeout", Value: "42"},
				}},
				{Name: "insecureSkipVerify", Value: "true"},
				{Name: "maxIdleConnsPerHost", Value: "42"},
				{Name: "rootCAs", Value: "║24║foobar║foobar"},
			}},
			{Name: "tracing", Children: []*parser.Node{
				{Name: "datadog", Children: []*parser.Node{
					{Name: "bagagePrefixHeaderName", Value: "foobar"},
					{Name: "debug", Value: "true"},
					{Name: "globalTag", Value: "foobar"},
					{Name: "localAgentHostPort", Value: "foobar"},
					{Name: "parentIDHeaderName", Value: "foobar"},
					{Name: "prioritySampling", Value: "true"},
					{Name: "samplingPriorityHeaderName", Value: "foobar"},
					{Name: "traceIDHeaderName", Value: "foobar"},
				}},
				{Name: "haystack", Children: []*parser.Node{
					{Name: "globalTag", Value: "foobar"},
					{Name: "localAgentHost", Value: "foobar"},
					{Name: "localAgentPort", Value: "42"},
					{Name: "parentIDHeaderName", Value: "foobar"},
					{Name: "spanIDHeaderName", Value: "foobar"},
					{Name: "traceIDHeaderName", Value: "foobar"},
				}},
				{Name: "instana", Children: []*parser.Node{
					{Name: "localAgentHost", Value: "foobar"},
					{Name: "localAgentPort", Value: "42"},
					{Name: "logLevel", Value: "foobar"},
				}},
				{Name: "jaeger", Children: []*parser.Node{
					{Name: "gen128Bit", Value: "true"},
					{Name: "localAgentHostPort", Value: "foobar"},
					{Name: "propagation", Value: "foobar"},
					{Name: "samplingParam", Value: "42"},
					{Name: "samplingServerURL", Value: "foobar"},
					{Name: "samplingType", Value: "foobar"},
					{Name: "traceContextHeaderName", Value: "foobar"},
				}},
				{Name: "serviceName", Value: "foobar"},
				{Name: "spanNameLimit", Value: "42"},
				{Name: "zipkin", Children: []*parser.Node{
					{Name: "httpEndpoint", Value: "foobar"},
					{Name: "id128Bit", Value: "true"},
					{Name: "sameSpan", Value: "true"},
					{Name: "sampleRate", Value: "42"},
				}},
			}},
		},
	}

	assert.Equal(t, expected, node)
}
