package scoped

import (
	"io/fs"
	"path/filepath"

	"koti.casa/numenor-labs/dsfx/internal/lib/disk"
)

// StorageScope is an interface that extends the disk.Disk interface by ensuring
// that all file operations are limited to a specific folder on the disk, which
// provides a dedicated storage scope that is isolated from other file operations.
type StorageScope interface {
	disk.Disk

	// Scope returns the storage scope as a string.
	Scope() string
}

// scoped is a concrete implementation of the StorageScope interface.
type scoped struct {
	disk  disk.Disk
	scope string
}

// New creates a new StorageScope with the specified scope.
func New(disk disk.Disk, scope string) StorageScope {
	return &scoped{disk, scope}
}

// Create implements disk.Disk.
func (s *scoped) Create(name string) (disk.File, error) {
	return s.disk.Create(s.path(name))
}

// Mkdir implements disk.Disk.
func (s *scoped) Mkdir(name string, perm fs.FileMode) error {
	return s.disk.Mkdir(s.path(name), perm)
}

// MkdirAll implements disk.Disk.
func (s *scoped) MkdirAll(name string, perm fs.FileMode) error {
	return s.disk.MkdirAll(s.path(name), perm)
}

// Open implements disk.Disk.
func (s *scoped) Open(name string) (disk.File, error) {
	return s.disk.Open(s.path(name))
}

// Remove implements disk.Disk.
func (s *scoped) Remove(name string) error {
	return s.disk.Remove(s.path(name))
}

// Stat implements disk.Disk.
func (s *scoped) Stat(name string) (fs.FileInfo, error) {
	return s.disk.Stat(s.path(name))
}

// Scope implements StorageScope.
func (s *scoped) Scope() string {
	return s.scope
}

// path is a helper method that returns the full path for a given path relative
// to the storage scope. This ensures that all file operations are performed
// within the defined scope.
func (s *scoped) path(path string) string {
	return filepath.Join(s.scope, path)
}