package filestore

import "errors"

// Error codes for file store operations
const (
	ErrCodeNotFound       = "FILE_NOT_FOUND"
	ErrCodeUploadFailed   = "UPLOAD_FAILED"
	ErrCodeDownloadFailed = "DOWNLOAD_FAILED"
	ErrCodeDeleteFailed   = "DELETE_FAILED"
	ErrCodeInvalidInput   = "INVALID_INPUT"
	ErrCodeFileTooLarge   = "FILE_TOO_LARGE"
	ErrCodeUnsupported    = "UNSUPPORTED_FILE_TYPE"
	ErrCodeDuplicate      = "DUPLICATE_FILE"
	ErrCodeAccessDenied   = "ACCESS_DENIED"
)

// FileStoreError represents a file store operation error
type FileStoreError struct {
	Code    string
	Message string
	Cause   error
}

// Error implements the error interface
func (e *FileStoreError) Error() string {
	if e.Cause != nil {
		return e.Message + ": " + e.Cause.Error()
	}
	return e.Message
}

// NewError creates a new FileStoreError
func NewError(code, message string) *FileStoreError {
	return &FileStoreError{
		Code:    code,
		Message: message,
		Cause:   nil,
	}
}

// NewErrorWithCause creates a new FileStoreError with an underlying cause
func NewErrorWithCause(code, message string, cause error) *FileStoreError {
	return &FileStoreError{
		Code:    code,
		Message: message,
		Cause:   cause,
	}
}

// Predefined errors
var (
	ErrFileNotFound    = NewError(ErrCodeNotFound, "file not found")
	ErrUploadFailed    = NewError(ErrCodeUploadFailed, "file upload failed")
	ErrDownloadFailed  = NewError(ErrCodeDownloadFailed, "file download failed")
	ErrDeleteFailed    = NewError(ErrCodeDeleteFailed, "file deletion failed")
	ErrInvalidInput    = NewError(ErrCodeInvalidInput, "invalid input")
	ErrFileTooLarge    = NewError(ErrCodeFileTooLarge, "file size exceeds maximum limit")
	ErrUnsupportedType = NewError(ErrCodeUnsupported, "unsupported file type")
	ErrDuplicateFile   = NewError(ErrCodeDuplicate, "file already exists")
	ErrAccessDenied    = NewError(ErrCodeAccessDenied, "access denied")
)

// IsNotFound checks if an error is a not found error
func IsNotFound(err error) bool {
	var fse *FileStoreError
	if errors.As(err, &fse) {
		return fse.Code == ErrCodeNotFound
	}
	return false
}

// IsFileTooLarge checks if an error is a file too large error
func IsFileTooLarge(err error) bool {
	var fse *FileStoreError
	if errors.As(err, &fse) {
		return fse.Code == ErrCodeFileTooLarge
	}
	return false
}

// IsUnsupportedType checks if an error is an unsupported type error
func IsUnsupportedType(err error) bool {
	var fse *FileStoreError
	if errors.As(err, &fse) {
		return fse.Code == ErrCodeUnsupported
	}
	return false
}
