// Copyright (C) 2022 Marius Schellenberger

package filter

import (
	stdfs "io/fs"
	"os"
	"regexp"

	"cachefs/pkg/provider"
)

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

type FS struct {
	provider.FS
	re *regexp.Regexp
}

func NewFS(fs provider.FS, re *regexp.Regexp) (*FS, error) {
	return &FS{
		FS: fs,
		re: re,
	}, nil
}

func (fs *FS) match(p string) error {
	if fs.re.MatchString(p) {
		return nil
	}
	return stdfs.ErrNotExist
}

func (fs *FS) Stat(p string) (stdfs.FileInfo, error) {
	err := fs.match(p)
	if err != nil {
		return nil, err
	}
	return fs.FS.Stat(p)
}

func (fs *FS) Remove(p string) error {
	err := fs.match(p)
	if err != nil {
		return err
	}
	return fs.FS.Remove(p)
}

func (fs *FS) Open(p string) (provider.File, error) {
	err := fs.match(p)
	if err != nil {
		return nil, err
	}
	f, err := fs.FS.Open(p)
	if err != nil {
		return nil, err
	}
	return newFile(f, fs, p)
}

func (fs *FS) OpenFile(p string, flags int, mode os.FileMode) (provider.File, error) {
	err := fs.match(p)
	if err != nil {
		return nil, err
	}
	f, err := fs.FS.OpenFile(p, flags, mode)
	if err != nil {
		return nil, err
	}
	return newFile(f, fs, p)
}

func (fs *FS) MkdirAll(p string, mode os.FileMode) error {
	err := fs.match(p)
	if err != nil {
		return err
	}
	return fs.FS.MkdirAll(p, mode)
}
