// Copyright 2020 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 embedtest

import (
	"embed"
	"errors"
	"io"
	"io/fs"
	"reflect"
	"slices"
	"testing"
	"testing/fstest"
)

//go:embed testdata/h*.txt
//go:embed c*.txt testdata/g*.txt
var global embed.FS

//go:embed c*txt
var concurrency string

//go:embed testdata/g*.txt
var glass []byte

func testFiles(t *testing.T, f embed.FS, name, data string) {
	t.Helper()
	d, err := f.ReadFile(name)
	if err != nil {
		t.Error(err)
		return
	}
	if string(d) != data {
		t.Errorf("read %v = %q, want %q", name, d, data)
	}
}

func testString(t *testing.T, s, name, data string) {
	t.Helper()
	if s != data {
		t.Errorf("%v = %q, want %q", name, s, data)
	}
}

func testDir(t *testing.T, f embed.FS, name string, expect ...string) {
	t.Helper()
	dirs, err := f.ReadDir(name)
	if err != nil {
		t.Error(err)
		return
	}
	var names []string
	for _, d := range dirs {
		name := d.Name()
		if d.IsDir() {
			name += "/"
		}
		names = append(names, name)
	}
	if !slices.Equal(names, expect) {
		t.Errorf("readdir %v = %v, want %v", name, names, expect)
	}
}

// Tests for issue 49514.
var _ = '"'
var _ = '\''
var _ = '🦆'

func TestGlobal(t *testing.T) {
	testFiles(t, global, "concurrency.txt", "Concurrency is not parallelism.\n")
	testFiles(t, global, "testdata/hello.txt", "hello, world\n")
	testFiles(t, global, "testdata/glass.txt", "I can eat glass and it doesn't hurt me.\n")

	if err := fstest.TestFS(global, "concurrency.txt", "testdata/hello.txt"); err != nil {
		t.Fatal(err)
	}

	testString(t, concurrency, "concurrency", "Concurrency is not parallelism.\n")
	testString(t, string(glass), "glass", "I can eat glass and it doesn't hurt me.\n")
}

//go:embed testdata
var testDirAll embed.FS

func TestDir(t *testing.T) {
	all := testDirAll
	testFiles(t, all, "testdata/hello.txt", "hello, world\n")
	testFiles(t, all, "testdata/i/i18n.txt", "internationalization\n")
	testFiles(t, all, "testdata/i/j/k/k8s.txt", "kubernetes\n")
	testFiles(t, all, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")

	testDir(t, all, ".", "testdata/")
	testDir(t, all, "testdata/i", "i18n.txt", "j/")
	testDir(t, all, "testdata/i/j", "k/")
	testDir(t, all, "testdata/i/j/k", "k8s.txt")
}

var (
	//go:embed testdata
	testHiddenDir embed.FS

	//go:embed testdata/*
	testHiddenStar embed.FS
)

func TestHidden(t *testing.T) {
	dir := testHiddenDir
	star := testHiddenStar

	t.Logf("//go:embed testdata")

	testDir(t, dir, "testdata",
		"-not-hidden/", "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt")

	t.Logf("//go:embed testdata/*")

	testDir(t, star, "testdata",
		"-not-hidden/", ".hidden/", "_hidden/", "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt")

	testDir(t, star, "testdata/.hidden",
		"fortune.txt", "more/") // but not .more or _more
}

func TestUninitialized(t *testing.T) {
	var uninitialized embed.FS
	testDir(t, uninitialized, ".")
	f, err := uninitialized.Open(".")
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()
	fi, err := f.Stat()
	if err != nil {
		t.Fatal(err)
	}
	if !fi.IsDir() {
		t.Errorf("in uninitialized embed.FS, . is not a directory")
	}
}

var (
	//go:embed "testdata/hello.txt"
	helloT []T
	//go:embed "testdata/hello.txt"
	helloUint8 []uint8
	//go:embed "testdata/hello.txt"
	helloEUint8 []EmbedUint8
	//go:embed "testdata/hello.txt"
	helloBytes EmbedBytes
	//go:embed "testdata/hello.txt"
	helloString EmbedString
)

type T byte
type EmbedUint8 uint8
type EmbedBytes []byte
type EmbedString string

// golang.org/issue/47735
func TestAliases(t *testing.T) {
	all := testDirAll
	want, e := all.ReadFile("testdata/hello.txt")
	if e != nil {
		t.Fatal("ReadFile:", e)
	}
	check := func(g any) {
		got := reflect.ValueOf(g)
		for i := 0; i < got.Len(); i++ {
			if byte(got.Index(i).Uint()) != want[i] {
				t.Fatalf("got %v want %v", got.Bytes(), want)
			}
		}
	}
	check(helloT)
	check(helloUint8)
	check(helloEUint8)
	check(helloBytes)
	check(helloString)
}

func TestOffset(t *testing.T) {
	file, err := testDirAll.Open("testdata/hello.txt")
	if err != nil {
		t.Fatal("Open:", err)
	}

	want := "hello, world\n"

	// Read the entire file.
	got := make([]byte, len(want))
	n, err := file.Read(got)
	if err != nil {
		t.Fatal("Read:", err)
	}
	if n != len(want) {
		t.Fatal("Read:", n)
	}
	if string(got) != want {
		t.Fatalf("Read: %q", got)
	}

	// Try to read one byte; confirm we're at the EOF.
	var buf [1]byte
	n, err = file.Read(buf[:])
	if err != io.EOF {
		t.Fatal("Read:", err)
	}
	if n != 0 {
		t.Fatal("Read:", n)
	}

	// Use seek to get the offset at the EOF.
	seeker := file.(io.Seeker)
	off, err := seeker.Seek(0, io.SeekCurrent)
	if err != nil {
		t.Fatal("Seek:", err)
	}
	if off != int64(len(want)) {
		t.Fatal("Seek:", off)
	}

	// Use Seek with an invalid whence.
	_, err = seeker.Seek(0, io.SeekEnd+5)
	if err == nil {
		t.Fatal("Seek: expected error for invalid whence")
	}
	if !errors.Is(err, fs.ErrInvalid) {
		t.Fatalf("Seek: expected fs.ErrInvalid, got %v", err)
	}

	// Use ReadAt to read the entire file, ignoring the offset.
	at := file.(io.ReaderAt)
	got = make([]byte, len(want))
	n, err = at.ReadAt(got, 0)
	if err != nil {
		t.Fatal("ReadAt:", err)
	}
	if n != len(want) {
		t.Fatalf("ReadAt: got %d bytes, want %d bytes", n, len(want))
	}
	if string(got) != want {
		t.Fatalf("ReadAt: got %q, want %q", got, want)
	}

	// Use ReadAt with non-zero offset.
	off = int64(7)
	part := want[off:]
	got = make([]byte, len(part))
	n, err = at.ReadAt(got, off)
	if err != nil {
		t.Fatal("ReadAt:", err)
	}
	if n != len(part) {
		t.Fatalf("ReadAt: got %d bytes, want %d bytes", n, len(part))
	}
	if string(got) != part {
		t.Fatalf("ReadAt: got %q, want %q", got, part)
	}

	// Use ReadAt with an offset at the end of the file.
	off = int64(len(want))
	got = make([]byte, 1)
	n, err = at.ReadAt(got, off)
	if err != io.EOF {
		t.Fatalf("ReadAt: expected io.EOF for offset at end of file")
	}
	if n != 0 {
		t.Fatalf("ReadAt: got %d bytes, want 0 bytes", n)
	}

	// Use ReadAt with an offset beyond the end of the file.
	off = int64(len(want) + 1)
	got = make([]byte, 1)
	n, err = at.ReadAt(got, off)
	if err != io.EOF {
		t.Fatalf("ReadAt: expected io.EOF for offset beyond end of file")
	}
	if n != 0 {
		t.Fatalf("ReadAt: got %d bytes, want 0 bytes", n)
	}
}
