/**
 * Go SDK for OpenFGA
 *
 * API version: 1.x
 * Website: https://openfga.dev
 * Documentation: https://openfga.dev/docs
 * Support: https://openfga.dev/community
 * License: [Apache-2.0](https://github.com/openfga/go-sdk/blob/main/LICENSE)
 *
 * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT.
 */

package openfga

import (
	"testing"
	"time"

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

func TestToPtr(t *testing.T) {
	now := time.Now()

	testCases := []struct {
		name     string
		value    interface{}
		expected interface{}
	}{
		{"bool_true", true, true},
		{"bool_false", false, false},
		{"int", 42, 42},
		{"int_zero", 0, 0},
		{"int32", int32(32), int32(32)},
		{"int64", int64(64), int64(64)},
		{"float32", float32(3.14), float32(3.14)},
		{"float64", float64(3.14159), float64(3.14159)},
		{"string", "test", "test"},
		{"string_empty", "", ""},
		{"time", now, now},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			switch v := tc.value.(type) {
			case bool:
				ptr := ToPtr(v)
				require.NotNil(t, ptr)
				assert.Equal(t, v, *ptr)
			case int:
				ptr := ToPtr(v)
				require.NotNil(t, ptr)
				assert.Equal(t, v, *ptr)
			case int32:
				ptr := ToPtr(v)
				require.NotNil(t, ptr)
				assert.Equal(t, v, *ptr)
			case int64:
				ptr := ToPtr(v)
				require.NotNil(t, ptr)
				assert.Equal(t, v, *ptr)
			case float32:
				ptr := ToPtr(v)
				require.NotNil(t, ptr)
				assert.Equal(t, v, *ptr)
			case float64:
				ptr := ToPtr(v)
				require.NotNil(t, ptr)
				assert.Equal(t, v, *ptr)
			case string:
				ptr := ToPtr(v)
				require.NotNil(t, ptr)
				assert.Equal(t, v, *ptr)
			case time.Time:
				ptr := ToPtr(v)
				require.NotNil(t, ptr)
				assert.Equal(t, v, *ptr)
			default:
				t.Errorf("Unsupported type: %T", v)
			}
		})
	}
}

func TestPtrFunctionsBackwardCompatibility(t *testing.T) {
	now := time.Now()

	testCases := []struct {
		name     string
		testFunc func(t *testing.T)
	}{
		{
			name: "PtrBool",
			testFunc: func(t *testing.T) {
				value := true
				ptr := PtrBool(value)
				require.NotNil(t, ptr)
				assert.Equal(t, value, *ptr)
			},
		},
		{
			name: "PtrInt",
			testFunc: func(t *testing.T) {
				value := 42
				ptr := PtrInt(value)
				require.NotNil(t, ptr)
				assert.Equal(t, value, *ptr)
			},
		},
		{
			name: "PtrInt32",
			testFunc: func(t *testing.T) {
				value := int32(32)
				ptr := PtrInt32(value)
				require.NotNil(t, ptr)
				assert.Equal(t, value, *ptr)
			},
		},
		{
			name: "PtrInt64",
			testFunc: func(t *testing.T) {
				value := int64(64)
				ptr := PtrInt64(value)
				require.NotNil(t, ptr)
				assert.Equal(t, value, *ptr)
			},
		},
		{
			name: "PtrFloat32",
			testFunc: func(t *testing.T) {
				value := float32(3.14)
				ptr := PtrFloat32(value)
				require.NotNil(t, ptr)
				assert.Equal(t, value, *ptr)
			},
		},
		{
			name: "PtrFloat64",
			testFunc: func(t *testing.T) {
				value := float64(3.14159)
				ptr := PtrFloat64(value)
				require.NotNil(t, ptr)
				assert.Equal(t, value, *ptr)
			},
		},
		{
			name: "PtrString",
			testFunc: func(t *testing.T) {
				value := "test"
				ptr := PtrString(value)
				require.NotNil(t, ptr)
				assert.Equal(t, value, *ptr)
			},
		},
		{
			name: "PtrTime",
			testFunc: func(t *testing.T) {
				ptr := PtrTime(now)
				require.NotNil(t, ptr)
				assert.Equal(t, now, *ptr)
			},
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, tc.testFunc)
	}
}

func TestToPtrVsPtrFunctions(t *testing.T) {
	now := time.Now()

	testCases := []struct {
		name     string
		testFunc func(t *testing.T)
	}{
		{
			name: "Bool",
			testFunc: func(t *testing.T) {
				value := true
				assert.Equal(t, *ToPtr(value), *PtrBool(value))
			},
		},
		{
			name: "Int",
			testFunc: func(t *testing.T) {
				value := 42
				assert.Equal(t, *ToPtr(value), *PtrInt(value))
			},
		},
		{
			name: "Int32",
			testFunc: func(t *testing.T) {
				value := int32(32)
				assert.Equal(t, *ToPtr(value), *PtrInt32(value))
			},
		},
		{
			name: "Int64",
			testFunc: func(t *testing.T) {
				value := int64(64)
				assert.Equal(t, *ToPtr(value), *PtrInt64(value))
			},
		},
		{
			name: "Float32",
			testFunc: func(t *testing.T) {
				value := float32(3.14)
				assert.Equal(t, *ToPtr(value), *PtrFloat32(value))
			},
		},
		{
			name: "Float64",
			testFunc: func(t *testing.T) {
				value := float64(3.14159)
				assert.Equal(t, *ToPtr(value), *PtrFloat64(value))
			},
		},
		{
			name: "String",
			testFunc: func(t *testing.T) {
				value := "test"
				assert.Equal(t, *ToPtr(value), *PtrString(value))
			},
		},
		{
			name: "Time",
			testFunc: func(t *testing.T) {
				assert.Equal(t, *ToPtr(now), *PtrTime(now))
			},
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, tc.testFunc)
	}
}

func TestValidatePathParameter(t *testing.T) {
	t.Parallel()

	testCases := []struct {
		name        string
		paramName   string
		paramValue  string
		expectError bool
		errorMsg    string
	}{
		{
			name:        "valid_non_empty_string",
			paramName:   "storeId",
			paramValue:  "01ARZ3NDEKTSV4RRFFQ69G5FAV",
			expectError: false,
		},
		{
			name:        "empty_string_returns_error",
			paramName:   "storeId",
			paramValue:  "",
			expectError: true,
			errorMsg:    "storeId is required and must be specified",
		},
		{
			name:        "whitespace_string_is_valid",
			paramName:   "modelId",
			paramValue:  " ",
			expectError: false,
		},
		{
			name:        "empty_string_different_parameter_name",
			paramName:   "authorizationModelId",
			paramValue:  "",
			expectError: true,
			errorMsg:    "authorizationModelId is required and must be specified",
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			err := validatePathParameter(tc.paramName, tc.paramValue)

			if tc.expectError {
				require.Error(t, err)
				assert.Equal(t, tc.errorMsg, err.Error())
			} else {
				assert.NoError(t, err)
			}
		})
	}
}

func TestValidateParameter(t *testing.T) {
	t.Parallel()

	testCases := []struct {
		name        string
		call        func() error
		expectError bool
		errorMsg    string
	}{
		{
			name:        "non_nil_pointer_is_valid",
			call:        func() error { return validateParameter("body", &CheckRequest{}) },
			expectError: false,
		},
		{
			name:        "nil_pointer_returns_error",
			call:        func() error { return validateParameter("body", (*CheckRequest)(nil)) },
			expectError: true,
			errorMsg:    "body is required and must be specified",
		},
		{
			name:        "nil_pointer_includes_parameter_name_in_error",
			call:        func() error { return validateParameter("request", (*WriteRequest)(nil)) },
			expectError: true,
			errorMsg:    "request is required and must be specified",
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			err := tc.call()

			if tc.expectError {
				require.Error(t, err)
				assert.Equal(t, tc.errorMsg, err.Error())
			} else {
				assert.NoError(t, err)
			}
		})
	}
}
