package ytdlp

import (
	"context"
	"io/fs"
	"os"
	"time"

	"git.kmsign.ru/royalcat/tstor/server/pkg/ctxbilly"
	"git.kmsign.ru/royalcat/tstor/server/src/vfs"
)

type SourceFS struct {
	service *Daemon
	source  Source

	fs ctxbilly.Filesystem

	vfs.DefaultFS
}

var _ vfs.Filesystem = (*SourceFS)(nil)

func newSourceFS(name string, fs ctxbilly.Filesystem, service *Daemon, source Source) *SourceFS {
	return &SourceFS{
		fs:        fs,
		service:   service,
		source:    source,
		DefaultFS: vfs.DefaultFS(name),
	}
}

// Open implements vfs.Filesystem.
func (s *SourceFS) Open(ctx context.Context, filename string) (vfs.File, error) {
	info, err := s.fs.Stat(ctx, filename)
	if err != nil {
		return nil, err
	}

	f, err := s.fs.OpenFile(ctx, filename, os.O_RDONLY, 0)
	if err != nil {
		return nil, err
	}

	return vfs.NewCtxBillyFile(info, f), nil
}

// ReadDir implements vfs.Filesystem.
func (s *SourceFS) ReadDir(ctx context.Context, path string) ([]fs.DirEntry, error) {
	infos, err := s.fs.ReadDir(ctx, path)
	if err != nil {
		return nil, err
	}

	entries := make([]fs.DirEntry, 0, len(infos))
	for _, info := range infos {
		entries = append(entries, vfs.NewFileInfo(info.Name(), info.Size(), time.Time{}))
	}

	return entries, nil
}

// Stat implements vfs.Filesystem.
func (s *SourceFS) Stat(ctx context.Context, filename string) (fs.FileInfo, error) {
	return s.fs.Stat(ctx, filename)
}

// Unlink implements vfs.Filesystem.
func (s *SourceFS) Unlink(ctx context.Context, filename string) error {
	return vfs.ErrNotImplemented
}

// Rename implements vfs.Filesystem.
func (s *SourceFS) Rename(ctx context.Context, oldpath string, newpath string) error {
	return vfs.ErrNotImplemented
}