// Copyright 2016 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 vfs_test

import (
	"fmt"
	"strings"
	"testing"
	"time"

	"golang.org/x/website/internal/godoc/vfs"
	"golang.org/x/website/internal/godoc/vfs/mapfs"
)

func TestNewNameSpace(t *testing.T) {

	// We will mount this filesystem under /fs1
	mount := mapfs.New(map[string]string{"fs1file": "abcdefgh"})

	// Existing process. This should give error on Stat("/")
	t1 := vfs.NameSpace{}
	t1.Bind("/fs1", mount, "/", vfs.BindReplace)

	// using NewNameSpace. This should work fine.
	t2 := vfs.NewNameSpace()
	t2.Bind("/fs1", mount, "/", vfs.BindReplace)

	testcases := map[string][]bool{
		"/":            {false, true},
		"/fs1":         {true, true},
		"/fs1/fs1file": {true, true},
	}

	fss := []vfs.FileSystem{t1, t2}

	for j, fs := range fss {
		for k, v := range testcases {
			_, err := fs.Stat(k)
			result := err == nil
			if result != v[j] {
				t.Errorf("fs: %d, testcase: %s, want: %v, got: %v, err: %s", j, k, v[j], result, err)
			}
		}
	}

	fi, err := t2.Stat("/")
	if err != nil {
		t.Fatal(err)
	}

	if fi.Name() != "/" {
		t.Errorf("t2.Name() : want:%s got:%s", "/", fi.Name())
	}

	if !fi.ModTime().IsZero() {
		t.Errorf("t2.ModTime() : want:%v got:%v", time.Time{}, fi.ModTime())
	}
}

func TestReadDirUnion(t *testing.T) {
	for _, tc := range []struct {
		desc       string
		ns         vfs.NameSpace
		path, want string
	}{
		{
			desc: "no_go_files",
			ns: func() vfs.NameSpace {
				rootFs := mapfs.New(map[string]string{
					"doc/a.txt":       "1",
					"doc/b.txt":       "1",
					"doc/dir1/d1.txt": "",
				})
				docFs := mapfs.New(map[string]string{
					"doc/a.txt":       "22",
					"doc/dir2/d2.txt": "",
				})
				ns := vfs.NameSpace{}
				ns.Bind("/", rootFs, "/", vfs.BindReplace)
				ns.Bind("/doc", docFs, "/doc", vfs.BindBefore)
				return ns
			}(),
			path: "/doc",
			want: "a.txt:2,b.txt:1,dir1:0,dir2:0",
		}, {
			desc: "have_go_files",
			ns: func() vfs.NameSpace {
				a := mapfs.New(map[string]string{
					"src/x/a.txt":        "",
					"src/x/suba/sub.txt": "",
				})
				b := mapfs.New(map[string]string{
					"src/x/b.go":         "package b",
					"src/x/subb/sub.txt": "",
				})
				c := mapfs.New(map[string]string{
					"src/x/c.txt":        "",
					"src/x/subc/sub.txt": "",
				})
				ns := vfs.NameSpace{}
				ns.Bind("/", a, "/", vfs.BindReplace)
				ns.Bind("/", b, "/", vfs.BindAfter)
				ns.Bind("/", c, "/", vfs.BindAfter)
				return ns
			}(),
			path: "/src/x",
			want: "b.go:9,suba:0,subb:0,subc:0",
		}, {
			desc: "empty_mount",
			ns: func() vfs.NameSpace {
				ns := vfs.NameSpace{}
				ns.Bind("/empty", mapfs.New(nil), "/empty", vfs.BindReplace)
				return ns
			}(),
			path: "/",
			want: "empty:0",
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			fis, err := tc.ns.ReadDir(tc.path)
			if err != nil {
				t.Fatal(err)
			}
			buf := &strings.Builder{}
			sep := ""
			for _, fi := range fis {
				fmt.Fprintf(buf, "%s%s:%d", sep, fi.Name(), fi.Size())
				sep = ","
			}
			if got := buf.String(); got != tc.want {
				t.Errorf("got %q; want %q", got, tc.want)
			}
		})
	}
}
