package service

import (
	"errors"
	"testing"
)

// =============================================================================
// Classified Error Tests
// =============================================================================

func TestClassifiedError(t *testing.T) {
	// Test error with message
	e1 := &classifiedError{message: "custom message", cause: errors.New("cause")}
	if e1.Error() != "custom message" {
		t.Errorf("Error() = %q, want %q", e1.Error(), "custom message")
	}

	// Test error with cause but no message
	e2 := &classifiedError{cause: errors.New("underlying error")}
	if e2.Error() != "underlying error" {
		t.Errorf("Error() = %q, want %q", e2.Error(), "underlying error")
	}

	// Test error with neither message nor cause
	e3 := &classifiedError{}
	if e3.Error() != "" {
		t.Errorf("Error() = %q, want empty string", e3.Error())
	}
}

func TestClassifiedErrorUnwrap(t *testing.T) {
	innerErr := errors.New("inner error")
	e := &classifiedError{message: "outer", cause: innerErr}

	unwrapped := e.Unwrap()
	if unwrapped != innerErr {
		t.Errorf("Unwrap() = %v, want %v", unwrapped, innerErr)
	}

	// Test errors.Is
	if !errors.Is(e, innerErr) {
		t.Error("errors.Is(e, innerErr) = false, want true")
	}
}

func TestNewRateLimitError(t *testing.T) {
	err := newRateLimitError("too many requests")

	// Should be a classifiedError
	var ce *classifiedError
	if !errors.As(err, &ce) {
		t.Errorf("errors.As(err, &classifiedError{}) = false")
	}

	// Should wrap ErrRateLimitExceeded
	if !errors.Is(err, ErrRateLimitExceeded) {
		t.Error("errors.Is(err, ErrRateLimitExceeded) = false")
	}

	// Error message should be "too many requests"
	if err.Error() != "too many requests" {
		t.Errorf("err.Error() = %q, want %q", err.Error(), "too many requests")
	}
}

func TestNewValidationError(t *testing.T) {
	err := newValidationError("invalid input")

	// Should be a classifiedError
	var ce *classifiedError
	if !errors.As(err, &ce) {
		t.Errorf("errors.As(err, &classifiedError{}) = false")
	}

	// Should wrap ErrValidationFailed
	if !errors.Is(err, ErrValidationFailed) {
		t.Error("errors.Is(err, ErrValidationFailed) = false")
	}

	// Error message should be "invalid input"
	if err.Error() != "invalid input" {
		t.Errorf("err.Error() = %q, want %q", err.Error(), "invalid input")
	}
}

func TestErrRateLimitExceeded(t *testing.T) {
	// ErrRateLimitExceeded is a sentinel error
	if ErrRateLimitExceeded.Error() != "rate limit exceeded" {
		t.Errorf("ErrRateLimitExceeded.Error() = %q, want %q", ErrRateLimitExceeded.Error(), "rate limit exceeded")
	}
}

func TestErrValidationFailed(t *testing.T) {
	// ErrValidationFailed is a sentinel error
	if ErrValidationFailed.Error() != "validation failed" {
		t.Errorf("ErrValidationFailed.Error() = %q, want %q", ErrValidationFailed.Error(), "validation failed")
	}
}
