package liber

import (
	"os"
	"path/filepath"
	"strings"
)

type FileStorage struct {
	Root    string
	Nesting int
}

func NewFileStorage(root string, nesting int) *FileStorage {
	return &FileStorage{
		Root:    root,
		Nesting: nesting,
	}
}

// Path of the file corresponding to the given key, relative to the
// root directory.
func (s *FileStorage) Path(key string) string {
	var parts []string
	for i := 0; i < s.Nesting; i++ {
		if i >= len(key) {
			break
		}
		parts = append(parts, key[i:i+1])
	}
	parts = append(parts, key)
	return filepath.Join(parts...)
}

// Create a new file for the given key.
func (s *FileStorage) Create(path string) (*os.File, error) {
	p := filepath.Join(s.Root, path)
	if err := os.MkdirAll(filepath.Dir(p), 0700); err != nil {
		return nil, err
	}
	return os.Create(p)
}

// Open a file.
func (s *FileStorage) Open(path string) (*os.File, error) {
	if strings.HasPrefix(path, "/") {
		return os.Open(path)
	}
	return os.Open(filepath.Join(s.Root, path))
}

// Rename oldpath to newpath.
func (s *FileStorage) Rename(oldpath, newpath string) error {
	if !strings.HasPrefix(oldpath, "/") {
		oldpath = filepath.Join(s.Root, oldpath)
	}
	if !strings.HasPrefix(newpath, "/") {
		newpath = filepath.Join(s.Root, newpath)
	}
	return os.Rename(oldpath, newpath)
}