package ollama

import (
	"fmt"
)

// Error types for the Ollama SDK
var (
	// ErrInvalidConfig is returned when configuration is invalid
	ErrInvalidConfig = func(msg string) error {
		return &ConfigError{Message: msg}
	}

	// ErrInvalidRequest is returned when a request is invalid
	ErrInvalidRequest = func(msg string) error {
		return &RequestError{Message: msg}
	}

	// ErrModelNotFound is returned when a model is not found
	ErrModelNotFound = func(model string) error {
		return &ModelError{Message: fmt.Sprintf("model %s not found", model), Model: model}
	}

	// ErrModelPullFailed is returned when pulling a model fails
	ErrModelPullFailed = func(model string, reason string) error {
		return &ModelError{Message: fmt.Sprintf("failed to pull model %s: %s", model, reason), Model: model}
	}

	// ErrModelDeleteFailed is returned when deleting a model fails
	ErrModelDeleteFailed = func(model string, reason string) error {
		return &ModelError{Message: fmt.Sprintf("failed to delete model %s: %s", model, reason), Model: model}
	}

	// ErrGenerationFailed is returned when text generation fails
	ErrGenerationFailed = func(reason string) error {
		return &GenerationError{Message: fmt.Sprintf("generation failed: %s", reason)}
	}

	// ErrChatFailed is returned when chat fails
	ErrChatFailed = func(reason string) error {
		return &ChatError{Message: fmt.Sprintf("chat failed: %s", reason)}
	}

	// ErrEmbeddingFailed is returned when embedding generation fails
	ErrEmbeddingFailed = func(reason string) error {
		return &EmbeddingError{Message: fmt.Sprintf("embedding failed: %s", reason)}
	}

	// ErrConnectionFailed is returned when connection to Ollama fails
	ErrConnectionFailed = func(reason string) error {
		return &ConnectionError{Message: fmt.Sprintf("connection failed: %s", reason)}
	}

	// ErrTimeout is returned when a request times out
	ErrTimeout = func(operation string) error {
		return &TimeoutError{Message: fmt.Sprintf("timeout during %s", operation), Operation: operation}
	}

	// ErrRateLimitExceeded is returned when rate limit is exceeded
	ErrRateLimitExceeded = func() error {
		return &RateLimitError{Message: "rate limit exceeded"}
	}
)

// ConfigError represents a configuration error
type ConfigError struct {
	Message string
}

func (e *ConfigError) Error() string {
	return fmt.Sprintf("config error: %s", e.Message)
}

// RequestError represents a request validation error
type RequestError struct {
	Message string
}

func (e *RequestError) Error() string {
	return fmt.Sprintf("request error: %s", e.Message)
}

// ModelError represents a model-related error
type ModelError struct {
	Message string
	Model   string
}

func (e *ModelError) Error() string {
	return fmt.Sprintf("model error: %s", e.Message)
}

// GenerationError represents a text generation error
type GenerationError struct {
	Message string
}

func (e *GenerationError) Error() string {
	return fmt.Sprintf("generation error: %s", e.Message)
}

// ChatError represents a chat error
type ChatError struct {
	Message string
}

func (e *ChatError) Error() string {
	return fmt.Sprintf("chat error: %s", e.Message)
}

// EmbeddingError represents an embedding generation error
type EmbeddingError struct {
	Message string
}

func (e *EmbeddingError) Error() string {
	return fmt.Sprintf("embedding error: %s", e.Message)
}

// ConnectionError represents a connection error
type ConnectionError struct {
	Message string
}

func (e *ConnectionError) Error() string {
	return fmt.Sprintf("connection error: %s", e.Message)
}

// TimeoutError represents a timeout error
type TimeoutError struct {
	Message   string
	Operation string
}

func (e *TimeoutError) Error() string {
	return fmt.Sprintf("timeout error: %s", e.Message)
}

// RateLimitError represents a rate limit error
type RateLimitError struct {
	Message string
}

func (e *RateLimitError) Error() string {
	return fmt.Sprintf("rate limit error: %s", e.Message)
}
