// Copyright 2011 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

import (
	"fmt"
	"io"
	"os"
	pathpkg "path"
	"sort"
	"strings"
	"time"
)

// Setting debugNS = true will enable debugging prints about
// name space translations.
const debugNS = false

// A NameSpace is a file system made up of other file systems
// mounted at specific locations in the name space.
//
// The representation is a map from mount point locations
// to the list of file systems mounted at that location.  A traditional
// Unix mount table would use a single file system per mount point,
// but we want to be able to mount multiple file systems on a single
// mount point and have the system behave as if the union of those
// file systems were present at the mount point.
// For example, if the OS file system has a Go installation in
// c:\Go and additional Go path trees in  d:\Work1 and d:\Work2, then
// this name space creates the view we want for the godoc server:
//
//	NameSpace{
//		"/": {
//			{old: "/", fs: OS(`c:\Go`), new: "/"},
//		},
//		"/src/pkg": {
//			{old: "/src/pkg", fs: OS(`c:\Go`), new: "/src/pkg"},
//			{old: "/src/pkg", fs: OS(`d:\Work1`), new: "/src"},
//			{old: "/src/pkg", fs: OS(`d:\Work2`), new: "/src"},
//		},
//	}
//
// This is created by executing:
//
//	ns := NameSpace{}
//	ns.Bind("/", OS(`c:\Go`), "/", BindReplace)
//	ns.Bind("/src/pkg", OS(`d:\Work1`), "/src", BindAfter)
//	ns.Bind("/src/pkg", OS(`d:\Work2`), "/src", BindAfter)
//
// A particular mount point entry is a triple (old, fs, new), meaning that to
// operate on a path beginning with old, replace that prefix (old) with new
// and then pass that path to the FileSystem implementation fs.
//
// If you do not explicitly mount a FileSystem at the root mountpoint "/" of the
// NameSpace like above, Stat("/") will return a "not found" error which could
// break typical directory traversal routines. In such cases, use NewNameSpace()
// to get a NameSpace pre-initialized with an emulated empty directory at root.
//
// Given this name space, a ReadDir of /src/pkg/code will check each prefix
// of the path for a mount point (first /src/pkg/code, then /src/pkg, then /src,
// then /), stopping when it finds one.  For the above example, /src/pkg/code
// will find the mount point at /src/pkg:
//
//	{old: "/src/pkg", fs: OS(`c:\Go`), new: "/src/pkg"},
//	{old: "/src/pkg", fs: OS(`d:\Work1`), new: "/src"},
//	{old: "/src/pkg", fs: OS(`d:\Work2`), new: "/src"},
//
// ReadDir will when execute these three calls and merge the results:
//
//	OS(`c:\Go`).ReadDir("/src/pkg/code")
//	OS(`d:\Work1').ReadDir("/src/code")
//	OS(`d:\Work2').ReadDir("/src/code")
//
// Note that the "/src/pkg" in "/src/pkg/code" has been replaced by
// just "/src" in the final two calls.
//
// OS is itself an implementation of a file system: it implements
// OS(`c:\Go`).ReadDir("/src/pkg/code") as ioutil.ReadDir(`c:\Go\src\pkg\code`).
//
// Because the new path is evaluated by fs (here OS(root)), another way
// to read the mount table is to mentally combine fs+new, so that this table:
//
//	{old: "/src/pkg", fs: OS(`c:\Go`), new: "/src/pkg"},
//	{old: "/src/pkg", fs: OS(`d:\Work1`), new: "/src"},
//	{old: "/src/pkg", fs: OS(`d:\Work2`), new: "/src"},
//
// reads as:
//
//	"/src/pkg" -> c:\Go\src\pkg
//	"/src/pkg" -> d:\Work1\src
//	"/src/pkg" -> d:\Work2\src
//
// An invariant (a redundancy) of the name space representation is that
// ns[mtpt][i].old is always equal to mtpt (in the example, ns["/src/pkg"]'s
// mount table entries always have old == "/src/pkg").  The 'old' field is
// useful to callers, because they receive just a []mountedFS and not any
// other indication of which mount point was found.
//
type NameSpace map[string][]mountedFS

// A mountedFS handles requests for path by replacing
// a prefix 'old' with 'new' and then calling the fs methods.
type mountedFS struct {
	old string
	fs  FileSystem
	new string
}

// hasPathPrefix reports whether x == y or x == y + "/" + more.
func hasPathPrefix(x, y string) bool {
	return x == y || strings.HasPrefix(x, y) && (strings.HasSuffix(y, "/") || strings.HasPrefix(x[len(y):], "/"))
}

// translate translates path for use in m, replacing old with new.
//
// mountedFS{"/src/pkg", fs, "/src"}.translate("/src/pkg/code") == "/src/code".
func (m mountedFS) translate(path string) string {
	path = pathpkg.Clean("/" + path)
	if !hasPathPrefix(path, m.old) {
		panic("translate " + path + " but old=" + m.old)
	}
	return pathpkg.Join(m.new, path[len(m.old):])
}

func (NameSpace) String() string {
	return "ns"
}

// Fprint writes a text representation of the name space to w.
func (ns NameSpace) Fprint(w io.Writer) {
	fmt.Fprint(w, "name space {\n")
	var all []string
	for mtpt := range ns {
		all = append(all, mtpt)
	}
	sort.Strings(all)
	for _, mtpt := range all {
		fmt.Fprintf(w, "\t%s:\n", mtpt)
		for _, m := range ns[mtpt] {
			fmt.Fprintf(w, "\t\t%s %s\n", m.fs, m.new)
		}
	}
	fmt.Fprint(w, "}\n")
}

// clean returns a cleaned, rooted path for evaluation.
// It canonicalizes the path so that we can use string operations
// to analyze it.
func (NameSpace) clean(path string) string {
	return pathpkg.Clean("/" + path)
}

type BindMode int

const (
	BindReplace BindMode = iota
	BindBefore
	BindAfter
)

// Bind causes references to old to redirect to the path new in newfs.
// If mode is BindReplace, old redirections are discarded.
// If mode is BindBefore, this redirection takes priority over existing ones,
// but earlier ones are still consulted for paths that do not exist in newfs.
// If mode is BindAfter, this redirection happens only after existing ones
// have been tried and failed.
func (ns NameSpace) Bind(old string, newfs FileSystem, new string, mode BindMode) {
	old = ns.clean(old)
	new = ns.clean(new)
	m := mountedFS{old, newfs, new}
	var mtpt []mountedFS
	switch mode {
	case BindReplace:
		mtpt = append(mtpt, m)
	case BindAfter:
		mtpt = append(mtpt, ns.resolve(old)...)
		mtpt = append(mtpt, m)
	case BindBefore:
		mtpt = append(mtpt, m)
		mtpt = append(mtpt, ns.resolve(old)...)
	}

	// Extend m.old, m.new in inherited mount point entries.
	for i := range mtpt {
		m := &mtpt[i]
		if m.old != old {
			if !hasPathPrefix(old, m.old) {
				// This should not happen.  If it does, panic so
				// that we can see the call trace that led to it.
				panic(fmt.Sprintf("invalid Bind: old=%q m={%q, %s, %q}", old, m.old, m.fs.String(), m.new))
			}
			suffix := old[len(m.old):]
			m.old = pathpkg.Join(m.old, suffix)
			m.new = pathpkg.Join(m.new, suffix)
		}
	}

	ns[old] = mtpt
}

// resolve resolves a path to the list of mountedFS to use for path.
func (ns NameSpace) resolve(path string) []mountedFS {
	path = ns.clean(path)
	for {
		if m := ns[path]; m != nil {
			if debugNS {
				fmt.Printf("resolve %s: %v\n", path, m)
			}
			return m
		}
		if path == "/" {
			break
		}
		path = pathpkg.Dir(path)
	}
	return nil
}

// Open implements the FileSystem Open method.
func (ns NameSpace) Open(path string) (ReadSeekCloser, error) {
	var err error
	for _, m := range ns.resolve(path) {
		if debugNS {
			fmt.Printf("tx %s: %v\n", path, m.translate(path))
		}
		tp := m.translate(path)
		r, err1 := m.fs.Open(tp)
		if err1 == nil {
			return r, nil
		}
		// IsNotExist errors in overlay FSes can mask real errors in
		// the underlying FS, so ignore them if there is another error.
		if err == nil || os.IsNotExist(err) {
			err = err1
		}
	}
	if err == nil {
		err = &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist}
	}
	return nil, err
}

// stat implements the FileSystem Stat and Lstat methods.
func (ns NameSpace) stat(path string, f func(FileSystem, string) (os.FileInfo, error)) (os.FileInfo, error) {
	var err error
	for _, m := range ns.resolve(path) {
		fi, err1 := f(m.fs, m.translate(path))
		if err1 == nil {
			return fi, nil
		}
		if err == nil {
			err = err1
		}
	}
	if err == nil {
		err = &os.PathError{Op: "stat", Path: path, Err: os.ErrNotExist}
	}
	return nil, err
}

func (ns NameSpace) Stat(path string) (os.FileInfo, error) {
	return ns.stat(path, FileSystem.Stat)
}

func (ns NameSpace) Lstat(path string) (os.FileInfo, error) {
	return ns.stat(path, FileSystem.Lstat)
}

// dirInfo is a trivial implementation of os.FileInfo for a directory.
type dirInfo string

func (d dirInfo) Name() string       { return string(d) }
func (d dirInfo) Size() int64        { return 0 }
func (d dirInfo) Mode() os.FileMode  { return os.ModeDir | 0555 }
func (d dirInfo) ModTime() time.Time { return startTime }
func (d dirInfo) IsDir() bool        { return true }
func (d dirInfo) Sys() interface{}   { return nil }

var startTime = time.Now()

// ReadDir implements the FileSystem ReadDir method.  It's where most of the magic is.
// (The rest is in resolve.)
//
// Logically, ReadDir must return the union of all the directories that are named
// by path.  In order to avoid misinterpreting Go packages, of all the directories
// that contain Go source code, we only include the files from the first,
// but we include subdirectories from all.
//
// ReadDir must also return directory entries needed to reach mount points.
// If the name space looks like the example in the type NameSpace comment,
// but c:\Go does not have a src/pkg subdirectory, we still want to be able
// to find that subdirectory, because we've mounted d:\Work1 and d:\Work2
// there.  So if we don't see "src" in the directory listing for c:\Go, we add an
// entry for it before returning.
//
func (ns NameSpace) ReadDir(path string) ([]os.FileInfo, error) {
	path = ns.clean(path)

	// List matching directories and determine whether any of them contain
	// Go files.
	var (
		dirs       [][]os.FileInfo
		goDirIndex = -1
		readDirErr error
	)

	for _, m := range ns.resolve(path) {
		dir, err := m.fs.ReadDir(m.translate(path))
		if err != nil {
			if readDirErr == nil {
				readDirErr = err
			}
			continue
		}

		dirs = append(dirs, dir)

		if goDirIndex < 0 {
			for _, f := range dir {
				if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {
					goDirIndex = len(dirs) - 1
					break
				}
			}
		}
	}

	// Build a list of files and subdirectories. If a directory contains Go files,
	// only include files from that directory. Otherwise, include files from
	// all directories. Include subdirectories from all directories regardless
	// of whether Go files are present.
	haveName := make(map[string]bool)
	var all []os.FileInfo
	for i, dir := range dirs {
		for _, f := range dir {
			name := f.Name()
			if !haveName[name] && (f.IsDir() || goDirIndex < 0 || goDirIndex == i) {
				all = append(all, f)
				haveName[name] = true
			}
		}
	}

	// Add any missing directories needed to reach mount points.
	for old := range ns {
		if hasPathPrefix(old, path) && old != path {
			// Find next element after path in old.
			elem := old[len(path):]
			elem = strings.TrimPrefix(elem, "/")
			if i := strings.Index(elem, "/"); i >= 0 {
				elem = elem[:i]
			}
			if !haveName[elem] {
				haveName[elem] = true
				all = append(all, dirInfo(elem))
			}
		}
	}

	if len(all) == 0 {
		return nil, readDirErr
	}

	sort.Sort(byName(all))
	return all, nil
}

// RootType returns the RootType for the given path in the namespace.
func (ns NameSpace) RootType(path string) RootType {
	// We resolve the given path to a list of mountedFS and then return
	// the root type for the filesystem which contains the path.
	for _, m := range ns.resolve(path) {
		_, err := m.fs.ReadDir(m.translate(path))
		// Found a match, return the filesystem's root type
		if err == nil {
			return m.fs.RootType(path)
		}
	}
	return ""
}

// byName implements sort.Interface.
type byName []os.FileInfo

func (f byName) Len() int           { return len(f) }
func (f byName) Less(i, j int) bool { return f[i].Name() < f[j].Name() }
func (f byName) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
