package lib

import (
	"encoding/json"
	"fmt"
	"reflect"
	"testing"
)

func parse(s string) map[string]interface{} {
	var m map[string]interface{}
	if err := json.Unmarshal([]byte(s), &m); err != nil {
		panic(s + ":" + err.Error())
	}
	return m
}

func TestPatchSliceOfMaps(t *testing.T) {
	tests := []struct {
		in, out  string
		skip     []string
		skipTree []string
	}{
		{
			in:  `{"a":{"b":"c"}}`,
			out: `{"a":{"b":"c"}}`,
		},
		{
			in:  `{"a":[{"b":"c"}]}`,
			out: `{"a":{"b":"c"}}`,
		},
		{
			in:  `{"a":[{"b":[{"c":"d"}]}]}`,
			out: `{"a":{"b":{"c":"d"}}}`,
		},
		{
			in:   `{"a":[{"b":"c"}]}`,
			out:  `{"a":[{"b":"c"}]}`,
			skip: []string{"a"},
		},
		{
			in: `{
				"Services": [
					{
						"checks": [
							{
								"header": [
									{"a":"b"}
								]
							}
						]
					}
				]
			}`,
			out: `{
				"Services": [
					{
						"checks": [
							{
								"header": {"a":"b"}
							}
						]
					}
				]
			}`,
			skip: []string{"services", "services.checks"},
		},
		{
			// inspired by the 'config_entries.bootstrap.*' structure for configs
			in: `
			{
				"a": [
					{
						"b": [
							{
								"c": "val1",
								"d": {
									"foo": "bar"
								},
								"e": [
									{
										"super": "duper"
									}
								]
							}
						]
					}
				]
			}
			`,
			out: `
			{
				"a": {
					"b": [
						{
							"c": "val1",
							"d": {
								"foo": "bar"
							},
							"e": [
								{
									"super": "duper"
								}
							]
						}
					]
				}
			}
			`,
			skipTree: []string{"a.b"},
		},
	}

	for i, tt := range tests {
		desc := fmt.Sprintf("%02d: %s -> %s skip: %v", i, tt.in, tt.out, tt.skip)
		t.Run(desc, func(t *testing.T) {
			out := PatchSliceOfMaps(parse(tt.in), tt.skip, tt.skipTree)
			if got, want := out, parse(tt.out); !reflect.DeepEqual(got, want) {
				t.Fatalf("\ngot  %#v\nwant %#v", got, want)
			}
		})
	}
}
