package store

import (
	"context"
	"io"
	"time"
)

// FileInfo represents metadata and attributes of a file or directory.
type FileInfo struct {
	Path   string // Path represents the relative or absolute location of the file or directory in the filesystem.
	Size   int64  // Size represents the size of the file in bytes.
	IsDir  bool   // IsDir indicates whether the FileInfo represents a directory.
	SHA256 string // SHA256 represents the SHA-256 checksum of the file for integrity verification.
}

// Snapshot represents a point-in-time capture of file system metadata and hierarchy.
type Snapshot struct {
	ID           string     // ID is the unique identifier of the snapshot.
	Name         string     // Name is the user-defined name of the snapshot.
	ParentID     string     // ParentID is the unique identifier of the parent snapshot, if one exists.
	CreationTime time.Time  // CreationTime is the timestamp indicating when the snapshot was created.
	Files        []FileInfo // Files represents a list of file metadata contained in the snapshot.
}

// SnapshotInfo provides basic metadata about a snapshot, including its ID, name, parent snapshot, and creation time.
type SnapshotInfo struct {
	ID           string    // Уникальный идентификатор
	Name         string    // Имя снапшота
	ParentID     string    // ID родительского снапшота
	CreationTime time.Time // Время создания
}

// MetadataStore определяет интерфейс для хранения и извлечения метаданных снапшотов.
type MetadataStore interface {
	// SaveSnapshotMetadata сохраняет полные метаданные снапшота, включая список файлов.
	// Если снапшот с таким ID уже существует, он должен быть перезаписан.
	SaveSnapshotMetadata(ctx context.Context, snap Snapshot) error

	// GetSnapshotMetadata извлекает полные метаданные снапшота по его ID.
	// Возвращает agate.ErrNotFound, если снапшот не найден.
	GetSnapshotMetadata(ctx context.Context, snapshotID string) (*Snapshot, error)

	// ListSnapshotsMetadata извлекает краткую информацию обо всех снапшотах.
	ListSnapshotsMetadata(ctx context.Context) ([]SnapshotInfo, error)

	// DeleteSnapshotMetadata удаляет метаданные снапшота по его ID.
	// Не должен возвращать ошибку, если снапшот не найден.
	DeleteSnapshotMetadata(ctx context.Context, snapshotID string) error

	// Close закрывает соединение с хранилищем метаданных.
	Close() error
}

// BlobStore определяет интерфейс для хранения и извлечения самих данных снапшотов (архивов).
type BlobStore interface {
	// StoreBlob сохраняет данные из reader как блоб для указанного snapshotID.
	// Возвращает путь или идентификатор сохраненного блоба и ошибку.
	StoreBlob(ctx context.Context, snapshotID string, reader io.Reader) (path string, err error)

	// RetrieveBlob возвращает io.ReadCloser для чтения содержимого блоба по snapshotID.
	// Вызывающая сторона ОБЯЗАНА закрыть ReadCloser.
	// Возвращает snapshot.ErrNotFound, если блоб не найден.
	RetrieveBlob(ctx context.Context, snapshotID string) (io.ReadCloser, error)

	// DeleteBlob удаляет блоб, связанный с snapshotID.
	// Не должен возвращать ошибку, если блоб не найден.
	DeleteBlob(ctx context.Context, snapshotID string) error

	// GetBlobPath возвращает путь к файлу блоба в файловой системе.
	// Это может быть полезно для функций пакета archive, которые работают с путями.
	// Возвращает agate.ErrNotFound, если блоб не найден.
	GetBlobPath(ctx context.Context, snapshotID string) (string, error)
}
