// 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.

package fstest

import (
	"errors"
	"internal/testenv"
	"io/fs"
	"os"
	"path/filepath"
	"slices"
	"strings"
	"testing"
)

func TestSymlink(t *testing.T) {
	testenv.MustHaveSymlink(t)

	tmp := t.TempDir()
	tmpfs := os.DirFS(tmp)

	if err := os.WriteFile(filepath.Join(tmp, "hello"), []byte("hello, world\n"), 0644); err != nil {
		t.Fatal(err)
	}

	if err := os.Symlink(filepath.Join(tmp, "hello"), filepath.Join(tmp, "hello.link")); err != nil {
		t.Fatal(err)
	}

	if err := TestFS(tmpfs, "hello", "hello.link"); err != nil {
		t.Fatal(err)
	}
}

func TestDash(t *testing.T) {
	m := MapFS{
		"a-b/a": {Data: []byte("a-b/a")},
	}
	if err := TestFS(m, "a-b/a"); err != nil {
		t.Error(err)
	}
}

type shuffledFS MapFS

func (fsys shuffledFS) Open(name string) (fs.File, error) {
	f, err := MapFS(fsys).Open(name)
	if err != nil {
		return nil, err
	}
	return &shuffledFile{File: f}, nil
}

type shuffledFile struct{ fs.File }

func (f *shuffledFile) ReadDir(n int) ([]fs.DirEntry, error) {
	dirents, err := f.File.(fs.ReadDirFile).ReadDir(n)
	// Shuffle in a deterministic way, all we care about is making sure that the
	// list of directory entries is not is the lexicographic order.
	//
	// We do this to make sure that the TestFS test suite is not affected by the
	// order of directory entries.
	slices.SortFunc(dirents, func(a, b fs.DirEntry) int {
		return strings.Compare(b.Name(), a.Name())
	})
	return dirents, err
}

func TestShuffledFS(t *testing.T) {
	fsys := shuffledFS{
		"tmp/one":   {Data: []byte("1")},
		"tmp/two":   {Data: []byte("2")},
		"tmp/three": {Data: []byte("3")},
	}
	if err := TestFS(fsys, "tmp/one", "tmp/two", "tmp/three"); err != nil {
		t.Error(err)
	}
}

// failPermFS is a filesystem that always fails with fs.ErrPermission.
type failPermFS struct{}

func (f failPermFS) Open(name string) (fs.File, error) {
	if !fs.ValidPath(name) {
		return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid}
	}
	return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrPermission}
}

func TestTestFSWrappedErrors(t *testing.T) {
	err := TestFS(failPermFS{})
	if err == nil {
		t.Fatal("error expected")
	}
	t.Logf("Error (expecting wrapped fs.ErrPermission):\n%v", err)

	if !errors.Is(err, fs.ErrPermission) {
		t.Errorf("error should be a wrapped ErrPermission: %#v", err)
	}

	// TestFS is expected to return a list of errors.
	// Enforce that the list can be extracted for browsing.
	var errs interface{ Unwrap() []error }
	if !errors.As(err, &errs) {
		t.Errorf("caller should be able to extract the errors as a list: %#v", err)
	} else {
		for _, err := range errs.Unwrap() {
			// ErrPermission is expected
			// but any other error must be reported.
			if !errors.Is(err, fs.ErrPermission) {
				t.Errorf("unexpected error: %v", err)
			}
		}
	}
}
