// Copyright (C) 2022 Marius Schellenberger

package os

import (
	"cachefs/pkg/provider"
	"io/fs"
	"os"
	"path"
	"path/filepath"

	"golang.org/x/sys/unix"
)

var _ provider.FS = (*FS)(nil)

type FS struct {
	root string
}

func NewFS(root string) (*FS, error) {
	return &FS{root}, nil
}

func (fs *FS) path(p string) string {
	return filepath.Join(fs.root, filepath.FromSlash(path.Clean("/"+p)))
}

func (fs *FS) Stat(p string) (fs.FileInfo, error) {
	return os.Stat(fs.path(p))
}

func (fs *FS) Remove(p string) error {
	return os.Remove(fs.path(p))
}

func (fs *FS) Open(p string) (provider.File, error) {
	return os.Open(fs.path(p))
}

func (fs *FS) OpenFile(p string, flags int, mode os.FileMode) (provider.File, error) {
	return os.OpenFile(fs.path(p), flags, mode)
}

func (fs *FS) MkdirAll(p string, mode os.FileMode) error {
	return os.MkdirAll(fs.path(p), mode)
}

func (fs *FS) Root() string {
	return fs.root
}

func (fs *FS) Fstat(fd uintptr) (int64, error) {
	var stat unix.Stat_t
	err := unix.Fstat(int(fd), &stat)
	return stat.Blocks, err
}

func (FS) Close() error {
	return nil
}
