// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build go1.16

package vfs

import (
	"io/fs"
	"os"
	"path"
	"strings"
)

// FromFS converts an fs.FS to the FileSystem interface.
func FromFS(fsys fs.FS) FileSystem {
	return &fsysToFileSystem{fsys}
}

type fsysToFileSystem struct {
	fsys fs.FS
}

func (f *fsysToFileSystem) fsPath(name string) string {
	name = path.Clean(name)
	if name == "/" {
		return "."
	}
	return strings.TrimPrefix(name, "/")
}

func (f *fsysToFileSystem) Open(name string) (ReadSeekCloser, error) {
	file, err := f.fsys.Open(f.fsPath(name))
	if err != nil {
		return nil, err
	}
	if rsc, ok := file.(ReadSeekCloser); ok {
		return rsc, nil
	}
	return &noSeekFile{f.fsPath(name), file}, nil
}

func (f *fsysToFileSystem) Lstat(name string) (os.FileInfo, error) {
	return fs.Stat(f.fsys, f.fsPath(name))
}

func (f *fsysToFileSystem) Stat(name string) (os.FileInfo, error) {
	return fs.Stat(f.fsys, f.fsPath(name))
}

func (f *fsysToFileSystem) RootType(name string) RootType { return "" }

func (f *fsysToFileSystem) ReadDir(name string) ([]os.FileInfo, error) {
	dirs, err := fs.ReadDir(f.fsys, f.fsPath(name))
	var infos []os.FileInfo
	for _, d := range dirs {
		info, err1 := d.Info()
		if err1 != nil {
			if err == nil {
				err = err1
			}
			continue
		}
		infos = append(infos, info)
	}
	return infos, err
}

func (f *fsysToFileSystem) String() string { return "io/fs" }

type noSeekFile struct {
	path string
	fs.File
}

func (f *noSeekFile) Seek(offset int64, whence int) (int64, error) {
	return 0, &fs.PathError{Op: "seek", Path: f.path, Err: fs.ErrInvalid}
}
