package errors

import (
	"fmt"
	"strconv"
	"testing"

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

func TestWrap(t *testing.T) {
	err := NewErrorf(K8SClientError, "")
	err2 := Wrap(UnrecognizedError, "", err)
	assert.Error(t, err2)
	assert.Contains(t, err.Error(), strconv.Itoa(int(err.Code())))
	assert.Contains(t, err2.Error(), strconv.Itoa(int(err.Code())))
	assert.Contains(t, err2.Error(), strconv.Itoa(int(err2.Code())))
}

func TestCode(t *testing.T) {
	err := NewErrorf(K8SClientError, "test error")
	assert.Equal(t, K8SClientError, err.Code())

	wrappedErr := Wrap(UnrecognizedError, "wrapped error", err)
	assert.Equal(t, UnrecognizedError, wrappedErr.Code())
	assert.Equal(t, wrappedErr.Code().Equal(int32(UnrecognizedError)), true)
	assert.Equal(t, wrappedErr.Code().GetHttpCode(), 500)
}

func TestError(t *testing.T) {
	// Test Is function
	err := New(K8SClientError, "k8s error")
	assert.True(t, Is(err, K8SClientError))
	assert.False(t, Is(err, UnrecognizedError))
	assert.False(t, Is(nil, K8SClientError))

	// Test non-Error type
	stdErr := fmt.Errorf("standard error")
	assert.False(t, Is(stdErr, K8SClientError))

	// Test Ignore function
	err1 := New(K8SClientError, "should be ignored")
	assert.Nil(t, Ignore(err1, K8SClientError))
	assert.Equal(t, err1, Ignore(err1, UnrecognizedError))
	assert.Nil(t, Ignore(nil, K8SClientError))

	// Test error wrapping
	cause := New(K8SClientError, "original error")
	wrapped := Wrap(UnrecognizedError, "wrapped error", cause)
	assert.False(t, Is(wrapped, K8SClientError))
	assert.True(t, Is(wrapped, UnrecognizedError))

	//Test IgnoreBy function
	err2 := New(K8SClientError, "should be ignored by function")
	result := IgnoreBy(func(err error) bool {
		return Is(err, K8SClientError)
	}, err2)
	assert.Nil(t, result)
}
