// Copyright 2022 schukai GmbH. All rights reserved.
// Use of this source code is governed by a AGPL-3.0
// license that can be found in the LICENSE file.

package xflags

import (
	"github.com/stretchr/testify/assert"
	"strconv"
	"testing"
)

type testExecutionStruct struct {
	callbackCounter int `ignore:"true"`

	// for tag shadow see TestFlagCopyToShadow
	Global1  bool `short:"a" long:"global1" description:"Global 1" shadow:"ValGlobal1"`
	Global2  bool `short:"b" long:"global2" description:"Global 2"`
	Command1 struct {
		Command1Flag1 bool `short:"c" long:"command1flag1" description:"Command 1 Flag 1"`
		Command1Flag2 bool `short:"d" long:"command1flag2" description:"Command 1 Flag 2" shadow:"ValCommand1Flag2"`
		Command2      struct {
			Command2Flag1 bool `short:"e" long:"command2flag1" description:"Command 2 Flag 1"`
			Command2Flag2 bool `short:"f" long:"command2flag2" description:"Command 2 Flag 2"`
		} `command:"command2" description:"Command 2" call:"Command2Callback" `
	} `command:"command1" description:"Command 1" call:"Command1Callback" `
	Command3 struct {
		Command3Flag1 bool `short:"g" long:"command3flag1" description:"Command 3 Flag 1"`
	} `command:"command3" description:"Command 3" call:"Command3Callback" `
}

func (c *testExecutionStruct) Command1Callback(s *Settings[testExecutionStruct]) {
	s.definitions.callbackCounter++
}

func (c *testExecutionStruct) Command2Callback(s *Settings[testExecutionStruct]) {
	s.definitions.callbackCounter++
}

func (c *testExecutionStruct) Command3Callback(s *Settings[testExecutionStruct]) {
	s.definitions.callbackCounter++
}

type testExecutionTestCases[C any] struct {
	name        string
	args        []string
	targetValue int
}

func TestExec(t *testing.T) {

	tests := []testExecutionTestCases[testExecutionStruct]{
		{
			name:        "test",
			args:        []string{"command1", "-c"},
			targetValue: 1,
		},
		{
			name:        "test",
			args:        []string{"command1", "command2", "-e"},
			targetValue: 2,
		}, {
			name:        "test",
			args:        []string{"-a", "command3"},
			targetValue: 1,
		},
	}

	for _, tt := range tests {
		t.Run(tt.args[0], func(t *testing.T) {
			settings := New(tt.name, testExecutionStruct{})
			assert.NotNil(t, settings)

			if settings.definitions.callbackCounter != 0 {
				t.Error("Callback counter should be 0")
			}

			settings.Parse(tt.args)
			settings.Execute()

			if settings.HasErrors() {
				t.Error("Should not have errors")
				t.Log(settings.Errors())
			}

			if settings.definitions.callbackCounter != tt.targetValue {
				t.Error("Callback counter should be " + strconv.Itoa(tt.targetValue) + " but is " + strconv.Itoa(settings.definitions.callbackCounter))
			}

			//tt.test(s)
		})
	}
}