package utils_test

/* ---------------------------------------------------------------- *
 * UNIT TESTING
 * ---------------------------------------------------------------- */

import (
	"logik/core/utils"
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
)

/* ---------------------------------------------------------------- *
 * TESTCASE JsonToArrayOfStrings
 * ---------------------------------------------------------------- */

func TestJsonToArrayOfStrings(test *testing.T) {
	var assert = assert.New(test)
	var result []string
	utils.JsonToArrayOfStrings("[]", &result)
	assert.ElementsMatch([]string{}, result)
	utils.JsonToArrayOfStrings("[ \"ganymed\" ]", &result)
	assert.ElementsMatch([]string{"ganymed"}, result)
	utils.JsonToArrayOfStrings("[ \"ganymed\", \"io\" ]", &result)
	assert.ElementsMatch([]string{"ganymed", "io"}, result)
	assert.Panics(func() { utils.JsonToArrayOfStrings("[ 178 ]", &result) }, "Should panic if converting not a JSON-encoded array of strings!")
	assert.Panics(func() { utils.JsonToArrayOfStrings("true", &result) }, "Should panic if converting not a JSON-encoded array of strings!")
	assert.Panics(func() { utils.JsonToArrayOfStrings("", &result) }, "Should panic if converting not a JSON-encoded array of strings!")
	assert.Panics(func() { utils.JsonToArrayOfStrings("nil", &result) }, "Should panic if converting not a JSON-encoded array of strings!")
	assert.Panics(func() { utils.JsonToArrayOfStrings("\"somestring\"", &result) }, "Should panic if converting not a JSON-encoded array of strings!")
	assert.Panics(func() { utils.JsonToArrayOfStrings("'somestring'", &result) }, "Should panic if converting not a JSON-encoded array of strings!")
}

/* ---------------------------------------------------------------- *
 * TESTCASE Min2, Max2, MinList, MaxList, SumList
 * ---------------------------------------------------------------- */

func TestMin(test *testing.T) {
	var assert = assert.New(test)
	assert.Equal(3, utils.Min2(3, 8))
	assert.Equal(8, utils.Min2(100, 8))
	assert.Equal(50, utils.MinList([]int{50}))
	assert.Equal(1, utils.MinList([]int{50, 1}))
	assert.Equal(2, utils.MinList([]int{50, 34, 10, 2, 8, 89}))
	assert.Panics(func() { utils.MinList([]int{}) }, "Min of list should panic on empty list!")
}

func TestMax(test *testing.T) {
	var assert = assert.New(test)
	assert.Equal(8, utils.Max2(3, 8))
	assert.Equal(100, utils.Max2(100, 8))
	assert.Equal(50, utils.MaxList([]int{50}))
	assert.Equal(50, utils.MaxList([]int{50, 1}))
	assert.Equal(89, utils.MaxList([]int{50, 34, 10, 2, 8, 89}))
	assert.Panics(func() { utils.MaxList([]int{}) }, "Max of list should panic on empty list!")
}

func TestSumList(test *testing.T) {
	var assert = assert.New(test)
	assert.Equal(0, utils.SumList([]int{}), "Sum of empty list should be 0.")
	assert.Equal(2198, utils.SumList([]int{2198}))
	assert.Equal(15, utils.SumList([]int{0, 1, 2, 3, 4, 5}))
	assert.Equal(1038, utils.SumList([]int{1000, 1, 37}))
	assert.Equal(237, utils.SumList([]int{1000, -800, 37}))
}

/* ---------------------------------------------------------------- *
 * TESTCASE SortStrings
 * ---------------------------------------------------------------- */

func TestSortStrings(test *testing.T) {
	var assert = assert.New(test)
	var list = []string{"katze", "Hund", "baby", "Pluto", "Saturn", "Mond"}
	// NOTE: here use .Equal and not .ElementsMatch, since order important.
	utils.SortStrings(&list)
	assert.Equal([]string{"baby", "Hund", "katze", "Mond", "Pluto", "Saturn"}, list)
}

/* ---------------------------------------------------------------- *
 * TESTCASE SortStrings
 * ---------------------------------------------------------------- */

func TestFilterStrings(test *testing.T) {
	var assert = assert.New(test)
	var list = []string{"abram", "aaron", "aardvark", "aarhus", "alaska", "eel", "aal"}
	var list2 = utils.FilterStrings(&list, func(x string) bool { return strings.HasPrefix(x, "aa") })
	assert.ElementsMatch([]string{"aaron", "aardvark", "aarhus", "aal"}, list2)
}

/* ---------------------------------------------------------------- *
 * TESTCASE UnionStrings2, UnionStringsInPlace, UnionStringsList
 * ---------------------------------------------------------------- */

func TestUnionStrings2(test *testing.T) {
	var assert = assert.New(test)
	var list1 = []string{"red", "blue", "blue", "green", "blue", "grey", "black", "green"}
	var list2 = []string{"yellow", "orange", "lila", "red"}
	var list = utils.UnionStrings2(list1, list2)
	assert.ElementsMatch([]string{"black", "blue", "green", "grey", "lila", "orange", "red", "yellow"}, list)
}

func TestUnionStringsInPlace(test *testing.T) {
	var assert = assert.New(test)
	var list1 = []string{"red", "blue", "green"}
	var list2 = []string{"yellow", "red", "blue", "red", "black"}
	utils.UnionStringsInPlace(&list1, list2)
	assert.ElementsMatch([]string{"black", "blue", "green", "red", "yellow"}, list1)
}

func TestUnionStringsList(test *testing.T) {
	var assert = assert.New(test)
	var list []string
	var lists [][]string
	lists = [][]string{{"red", "blue", "blue", "green"}, {"yellow", "red", "black"}}
	list = utils.UnionStringsList(lists)
	assert.ElementsMatch([]string{"black", "blue", "green", "red", "yellow"}, list)
}
