package storage

import (
	"context"
	"errors"
	"io"
)

// ── Errors ─────────────────────────────────

var (
	// ErrNotFound is returned when a requested object does not exist.
	ErrNotFound = errors.New("storage: object not found")

	// ErrNotConfigured is returned when storage operations are attempted
	// but no backend has been configured or the backend is unhealthy.
	ErrNotConfigured = errors.New("storage: backend not configured")
)

// ── ObjectStore Interface ──────────────────

// ObjectStore is the abstraction for blob storage.
// Implementations: PVC (filesystem), S3 (minio-go v7).
//
// Keys are slash-delimited paths relative to the storage root:
//
//	files/{channel_id}/{file_id}_{filename}
//
// Implementations must create intermediate directories as needed.
type ObjectStore interface {
	// Put writes data to the given key.
	// Creates parent directories as needed. Overwrites if exists.
	Put(ctx context.Context, key string, r io.Reader, size int64, contentType string) error

	// Get returns a reader for the given key.
	// Returns the reader, size in bytes, content type, and error.
	// Caller must close the returned reader.
	// Returns ErrNotFound if key does not exist.
	Get(ctx context.Context, key string) (io.ReadCloser, int64, string, error)

	// Delete removes the object at key.
	// No error if the key does not exist (idempotent).
	Delete(ctx context.Context, key string) error

	// DeletePrefix removes all objects under the given prefix.
	// Used for channel deletion (bulk cleanup).
	// Example: DeletePrefix(ctx, "files/{channel_id}/")
	DeletePrefix(ctx context.Context, prefix string) error

	// Exists checks if an object exists at key without reading it.
	Exists(ctx context.Context, key string) (bool, error)

	// Healthy returns nil if the backend is operational (writable).
	Healthy(ctx context.Context) error

	// Stats returns aggregate storage statistics.
	Stats(ctx context.Context) (*StorageStats, error)

	// Backend returns the backend type identifier ("pvc", "s3").
	Backend() string
}

// StorageStats holds aggregate storage metrics.
type StorageStats struct {
	Backend    string `json:"backend"`
	Path       string `json:"path,omitempty"`       // PVC only
	Endpoint   string `json:"endpoint,omitempty"`    // S3 only
	Bucket     string `json:"bucket,omitempty"`      // S3 only
	Healthy    bool   `json:"healthy"`
	Configured bool   `json:"configured"`
	TotalFiles int64  `json:"total_files"`
	TotalBytes int64  `json:"total_bytes"`
}
