package app

import (
	"testing"

	"coopcloud.tech/abra/cli/internal"
)

func TestGetSpecificVersion(t *testing.T) {
	tests := []struct {
		input          mockArgs
		expectedOutput string
	}{
		// No specified version when command has one or less args
		{mockArgs{}, ""},
		{mockArgs{[]string{"arg0"}}, ""},
		// Second in arg (index-1) is the specified result when command has more than 1 args
		{mockArgs{[]string{"arg0", "arg1"}}, "arg1"},
		{mockArgs{[]string{"arg0", "arg1", "arg2"}}, "arg1"},
	}

	for _, test := range tests {
		if test.expectedOutput != getSpecifiedVersion(&test.input) {
			t.Fatalf("result for %s should be %s", test.input, test.expectedOutput)
		}
	}
}

func TestValidateChaosXORVersion(t *testing.T) {
	tests := []struct {
		input          mockArgs
		isChaos        bool
		expectedResult bool
	}{
		// Chaos = true, Specified Version absent
		{mockArgs{}, true, true},
		// Chaos = false, Specified Version absent
		{mockArgs{}, false, true},
		// Chaos = true, Specified Version present
		{mockArgs{[]string{"arg0", "arg1"}}, true, false},
		// Chaos = false, Specified Version present
		{mockArgs{[]string{"arg0", "arg1", "arg2"}}, false, true},
	}

	for _, test := range tests {
		internal.Chaos = test.isChaos
		res, _ := validateChaosXORVersion(&test.input)
		if res != test.expectedResult {
			t.Fatalf(
				"When args are %s and Chaos mode is %t result needs to be %t",
				test.input,
				test.isChaos,
				test.expectedResult,
			)
		}
	}
}

type mockArgs struct {
	v []string
}

func (a *mockArgs) Get(n int) string {
	if len(a.v) > n {
		return a.v[n]
	}
	return ""
}

func (a *mockArgs) First() string {
	return a.Get(0)
}

func (a *mockArgs) Tail() []string {
	if a.Len() >= 2 {
		tail := a.v[1:]
		ret := make([]string, len(tail))
		copy(ret, tail)
		return ret
	}

	return []string{}
}

func (a *mockArgs) Len() int {
	return len(a.v)
}

func (a *mockArgs) Present() bool {
	return a.Len() != 0
}

func (a *mockArgs) Slice() []string {
	ret := make([]string, len(a.v))
	copy(ret, a.v)
	return ret
}
