package testutils

import (
	"testing"

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

// TableTestCase représente un cas de test dans une table-driven test (T0045)
type TableTestCase struct {
	Name        string
	Input       interface{}
	Expected    interface{}
	ExpectedErr error
	SetupFunc   func() interface{}
	CleanupFunc func(interface{})
}

// RunTableTests exécute une série de tests table-driven (T0045)
func RunTableTests(t *testing.T, testCases []TableTestCase, testFunc func(t *testing.T, tc TableTestCase)) {
	for _, tc := range testCases {
		t.Run(tc.Name, func(t *testing.T) {
			var setupResult interface{}
			if tc.SetupFunc != nil {
				setupResult = tc.SetupFunc()
			}

			if tc.CleanupFunc != nil {
				defer tc.CleanupFunc(setupResult)
			}

			testFunc(t, tc)
		})
	}
}

// RunTableSubTests exécute une série de tests table-driven avec sous-tests (T0045)
func RunTableSubTests(t *testing.T, testCases []TableTestCase, testFunc func(t *testing.T, tc TableTestCase)) {
	for _, tc := range testCases {
		t.Run(tc.Name, func(t *testing.T) {
			var setupResult interface{}
			if tc.SetupFunc != nil {
				setupResult = tc.SetupFunc()
			}

			if tc.CleanupFunc != nil {
				defer tc.CleanupFunc(setupResult)
			}

			testFunc(t, tc)
		})
	}
}

// AssertEqual helper pour assertions égales (T0045)
func AssertEqual(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) {
	assert.Equal(t, expected, actual, msgAndArgs...)
}

// AssertNotEqual helper pour assertions non égales (T0045)
func AssertNotEqual(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) {
	assert.NotEqual(t, expected, actual, msgAndArgs...)
}

// RequireNoError helper pour vérifier absence d'erreur (T0045)
func RequireNoError(t *testing.T, err error, msgAndArgs ...interface{}) {
	require.NoError(t, err, msgAndArgs...)
}

// RequireError helper pour vérifier présence d'erreur (T0045)
func RequireError(t *testing.T, err error, msgAndArgs ...interface{}) {
	require.Error(t, err, msgAndArgs...)
}

// AssertNil helper pour vérifier qu'une valeur est nil (T0045)
func AssertNil(t *testing.T, object interface{}, msgAndArgs ...interface{}) {
	assert.Nil(t, object, msgAndArgs...)
}

// AssertNotNil helper pour vérifier qu'une valeur n'est pas nil (T0045)
func AssertNotNil(t *testing.T, object interface{}, msgAndArgs ...interface{}) {
	assert.NotNil(t, object, msgAndArgs...)
}

// AssertTrue helper pour vérifier qu'une valeur est true (T0045)
func AssertTrue(t *testing.T, value bool, msgAndArgs ...interface{}) {
	assert.True(t, value, msgAndArgs...)
}

// AssertFalse helper pour vérifier qu'une valeur est false (T0045)
func AssertFalse(t *testing.T, value bool, msgAndArgs ...interface{}) {
	assert.False(t, value, msgAndArgs...)
}

// Example usage:
/*
func TestExample(t *testing.T) {
	testCases := []TableTestCase{
		{
			Name:     "valid input",
			Input:    42,
			Expected: "42",
		},
		{
			Name:        "invalid input",
			Input:       -1,
			ExpectedErr: errors.New("negative not allowed"),
		},
	}

	RunTableTests(t, testCases, func(t *testing.T, tc TableTestCase) {
		result, err := ProcessInput(tc.Input.(int))
		if tc.ExpectedErr != nil {
			assert.Error(t, err)
			return
		}
		RequireNoError(t, err)
		AssertEqual(t, tc.Expected, result)
	})
}
*/
