package agent

import (
	"bytes"
	"encoding/json"
	"testing"
)

func setupRawValuesTest(jsonInput string, t *testing.T) map[string]map[string]interface{} {
	unmarshaled := new(map[string]map[string]interface{})
	err := json.Unmarshal([]byte(jsonInput), unmarshaled)
	if err != nil {
		t.Fatalf("Could not unmarshal json input: %v", err)
	}
	return *unmarshaled
}

func checkRawValuesTest(rawValues map[string]json.RawMessage, path, expected string, t *testing.T) {
	if bytes.Compare(rawValues[path], []byte(expected)) != 0 {
		t.Errorf("Raw value %s at %s doesn't match expected %s", rawValues[path], path, expected)
	}
}

// TestGetRawValuesNumberValue tests GetRawValues with a number value
func TestGetRawValuesNumberValue(t *testing.T) {
	unmarshaled := setupRawValuesTest(`{"namespace": {"a": 1}}`, t)
	rawValues := GetRawValues(unmarshaled)
	checkRawValuesTest(rawValues, "namespace.a", "1", t)
}

// TestGetRawValuesStringValue tests GetRawValues with a string value.
func TestGetRawValuesStringValue(t *testing.T) {
	unmarshaled := setupRawValuesTest(`{"namespace": {"a": "test"}}`, t)
	rawValues := GetRawValues(unmarshaled)
	checkRawValuesTest(rawValues, "namespace.a", "\"test\"", t)
}

// TestGetRawValuesBooleanValue tests GetRawValues with a boolean value.
func TestGetRawValuesBooleanValue(t *testing.T) {
	unmarshaled := setupRawValuesTest(`{"namespace": {"a": true}}`, t)
	rawValues := GetRawValues(unmarshaled)
	checkRawValuesTest(rawValues, "namespace.a", "true", t)
}

// TestGetRawValuesNullValue tests GetRawValues with a null value.
func TestGetRawValuesNullValue(t *testing.T) {
	unmarshaled := setupRawValuesTest(`{"namespace": {"a": null}}`, t)
	rawValues := GetRawValues(unmarshaled)
	checkRawValuesTest(rawValues, "namespace.a", "null", t)
}

// TestGetRawValuesArrayValue tests GetRawValues with an array value.
func TestGetRawValuesArrayValue(t *testing.T) {
	unmarshaled := setupRawValuesTest(`{"namespace": {"a": [1, "b"]}}`, t)
	rawValues := GetRawValues(unmarshaled)
	checkRawValuesTest(rawValues, "namespace.a", "[1,\"b\"]", t)
}

// TestGetRawValuesNestedObject tests GetRawValues with a nested object.
func TestGetRawValuesNestedObject(t *testing.T) {
	unmarshaled := setupRawValuesTest(`{"namespace": {"a": {"b": 1}}}`, t)
	rawValues := GetRawValues(unmarshaled)
	checkRawValuesTest(rawValues, "namespace.a.b", "1", t)
}

// TestGetRawValuesExplicitSubkey tests GetRawValues with a explicit subkey.
func TestGetRawValuesExplicitSubkey(t *testing.T) {
	unmarshaled := setupRawValuesTest(`{"namespace": {"a.b": 1}}`, t)
	rawValues := GetRawValues(unmarshaled)
	checkRawValuesTest(rawValues, "namespace.a.b", "1", t)
}
