// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0

package pathfinder

import "testing"

type PathfindTestStruct1 struct {
	A    bool
	Sub1 struct {
		B    bool
		Bi   int
		Bs   string
		Bf   float64
		Sub2 struct {
			C  bool
			Ci int
			Cs string
			Cf float64

			Sub3 struct {
				D  bool
				Di int
				Ds string
				Df float64
			}
		}
	}
}

func TestPathFindError(t *testing.T) {

	s := PathfindTestStruct1{}

	_, err := GetValue[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.XX")
	if err == nil {
		t.Error("err == nil")
	}

}

func TestPathFindSetValueString(t *testing.T) {

	testData := map[string]string{
		"Sub1.B":            "true",
		"Sub1.Bi":           "2",
		"Sub1.Bs":           "3",
		"Sub1.Bf":           "4.0",
		"Sub1.Sub2.C":       "true",
		"Sub1.Sub2.Ci":      "2",
		"Sub1.Sub2.Cs":      "3",
		"Sub1.Sub2.Cf":      "4.0",
		"Sub1.Sub2.Sub3.D":  "true",
		"Sub1.Sub2.Sub3.Di": "2",
		"Sub1.Sub2.Sub3.Ds": "3",
		"Sub1.Sub2.Sub3.Df": "4.0",
	}

	for k, v := range testData {
		s := &PathfindTestStruct1{}
		err := SetValue[*PathfindTestStruct1](s, k, v)
		if err != nil {
			t.Error(err)
		}
	}
}

func TestPathFindGetValueFrom(t *testing.T) {

	s := PathfindTestStruct1{}

	s.Sub1.B = true
	s.Sub1.Bi = 2
	s.Sub1.Bs = "3"
	s.Sub1.Bf = 4.0

	v, err := GetValue[PathfindTestStruct1](s, "Sub1.B")
	if err != nil {
		t.Error(err)
	}

	if v != true {
		t.Error("v != true")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Bi")
	if err != nil {
		t.Error(err)
	}

	if v != 2 {
		t.Error("v != 2")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Bs")
	if err != nil {
		t.Error(err)
	}

	if v != "3" {
		t.Error("v != 3")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Bf")
	if err != nil {
		t.Error(err)
	}

	if v != 4.0 {
		t.Error("v != 4.0")
	}

	s.Sub1.Sub2.C = true
	s.Sub1.Sub2.Ci = 2
	s.Sub1.Sub2.Cs = "3"
	s.Sub1.Sub2.Cf = 4.0

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Sub2.C")
	if err != nil {
		t.Error(err)
	}

	if v != true {
		t.Error("v != true")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Sub2.Ci")
	if err != nil {
		t.Error(err)
	}

	if v != 2 {
		t.Error("v != 2")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Sub2.Cs")
	if err != nil {
		t.Error(err)
	}

	if v != "3" {
		t.Error("v != 3")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Sub2.Cf")
	if err != nil {
		t.Error(err)
	}

	if v != 4.0 {
		t.Error("v != 4.0")
	}

	s.Sub1.Sub2.Sub3.D = true
	s.Sub1.Sub2.Sub3.Di = 2
	s.Sub1.Sub2.Sub3.Ds = "3"
	s.Sub1.Sub2.Sub3.Df = 4.0

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.D")
	if err != nil {
		t.Error(err)

	}

	if v != true {
		t.Error("v != true")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Di")
	if err != nil {
		t.Error(err)
	}

	if v != 2 {
		t.Error("v != 2")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Ds")
	if err != nil {
		t.Error(err)
	}

	if v != "3" {
		t.Error("v != 3")
	}

	v, err = GetValue[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Df")
	if err != nil {
		t.Error(err)
	}

	if v != 4.0 {
		t.Error("v != 4.0")
	}

}

func TestPathFindSetValueFrom(t *testing.T) {
	s := &PathfindTestStruct1{}

	SetValue[*PathfindTestStruct1](s, "Sub1.B", "true")
	SetValue[*PathfindTestStruct1](s, "Sub1.Bi", "2")
	SetValue[*PathfindTestStruct1](s, "Sub1.Bs", "3")
	SetValue[*PathfindTestStruct1](s, "Sub1.Bf", "4.0")

	if s.Sub1.B != true {
		t.Error("s.Sub1.B != true")
	}

	if s.Sub1.Bi != 2 {
		t.Error("s.Sub1.Bi != 2")

	}

	if s.Sub1.Bs != "3" {
		t.Error("s.Sub1.Bs != 3")
	}

	if s.Sub1.Bf != 4.0 {
		t.Error("s.Sub1.Bf != 4.0")
	}

	SetValue[*PathfindTestStruct1](s, "Sub1.Sub2.C", "true")
	SetValue[*PathfindTestStruct1](s, "Sub1.Sub2.Ci", "2")
	SetValue[*PathfindTestStruct1](s, "Sub1.Sub2.Cs", "3")
	SetValue[*PathfindTestStruct1](s, "Sub1.Sub2.Cf", "4.0")

	if s.Sub1.Sub2.C != true {
		t.Error("s.Sub1.Sub2.C != true")

	}

	if s.Sub1.Sub2.Ci != 2 {
		t.Error("s.Sub1.Sub2.Ci != 2")

	}

	if s.Sub1.Sub2.Cs != "3" {
		t.Error("s.Sub1.Sub2.Cs != 3")

	}

	if s.Sub1.Sub2.Cf != 4.0 {
		t.Error("s.Sub1.Sub2.Cf != 4.0")

	}

	if s.Sub1.Sub2.Sub3.D != false {
		t.Error("s.Sub1.Sub2.Sub3.D != false")

	}

	SetValue[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.D", "true")
	SetValue[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Di", "2")
	SetValue[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Ds", "3")
	SetValue[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Df", "4.0")

	if s.Sub1.Sub2.Sub3.D != true {
		t.Error("s.Sub1.Sub2.Sub3.D != true")

	}

	if s.Sub1.Sub2.Sub3.Di != 2 {
		t.Error("s.Sub1.Sub2.Sub3.Di != 2")

	}

	if s.Sub1.Sub2.Sub3.Ds != "3" {
		t.Error("s.Sub1.Sub2.Sub3.Ds != 3")

	}

	if s.Sub1.Sub2.Sub3.Df != 4.0 {
		t.Error("s.Sub1.Sub2.Sub3.Df != 4.0")

	}

}