package buildutil

import (
	"fmt"
	"go/build"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strings"
	"time"
)

// FakeContext returns a build.Context for the fake file tree specified
// by pkgs, which maps package import paths to a mapping from file base
// names to contents.
//
// The fake Context has a GOROOT of "/go" and no GOPATH, and overrides
// the necessary file access methods to read from memory instead of the
// real file system.
//
// Unlike a real file tree, the fake one has only two levels---packages
// and files---so ReadDir("/go/src/") returns all packages under
// /go/src/ including, for instance, "math" and "math/big".
// ReadDir("/go/src/math/big") would return all the files in the
// "math/big" package.
//
func FakeContext(pkgs map[string]map[string]string) *build.Context {
	clean := func(filename string) string {
		f := path.Clean(filepath.ToSlash(filename))
		// Removing "/go/src" while respecting segment
		// boundaries has this unfortunate corner case:
		if f == "/go/src" {
			return ""
		}
		return strings.TrimPrefix(f, "/go/src/")
	}

	ctxt := build.Default // copy
	ctxt.GOROOT = "/go"
	ctxt.GOPATH = ""
	ctxt.Compiler = "gc"
	ctxt.IsDir = func(dir string) bool {
		dir = clean(dir)
		if dir == "" {
			return true // needed by (*build.Context).SrcDirs
		}
		return pkgs[dir] != nil
	}
	ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) {
		dir = clean(dir)
		var fis []os.FileInfo
		if dir == "" {
			// enumerate packages
			for importPath := range pkgs {
				fis = append(fis, fakeDirInfo(importPath))
			}
		} else {
			// enumerate files of package
			for basename := range pkgs[dir] {
				fis = append(fis, fakeFileInfo(basename))
			}
		}
		sort.Sort(byName(fis))
		return fis, nil
	}
	ctxt.OpenFile = func(filename string) (io.ReadCloser, error) {
		filename = clean(filename)
		dir, base := path.Split(filename)
		content, ok := pkgs[path.Clean(dir)][base]
		if !ok {
			return nil, fmt.Errorf("file not found: %s", filename)
		}
		return ioutil.NopCloser(strings.NewReader(content)), nil
	}
	ctxt.IsAbsPath = func(path string) bool {
		path = filepath.ToSlash(path)
		// Don't rely on the default (filepath.Path) since on
		// Windows, it reports virtual paths as non-absolute.
		return strings.HasPrefix(path, "/")
	}
	return &ctxt
}

type byName []os.FileInfo

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

type fakeFileInfo string

func (fi fakeFileInfo) Name() string    { return string(fi) }
func (fakeFileInfo) Sys() interface{}   { return nil }
func (fakeFileInfo) ModTime() time.Time { return time.Time{} }
func (fakeFileInfo) IsDir() bool        { return false }
func (fakeFileInfo) Size() int64        { return 0 }
func (fakeFileInfo) Mode() os.FileMode  { return 0644 }

type fakeDirInfo string

func (fd fakeDirInfo) Name() string    { return string(fd) }
func (fakeDirInfo) Sys() interface{}   { return nil }
func (fakeDirInfo) ModTime() time.Time { return time.Time{} }
func (fakeDirInfo) IsDir() bool        { return true }
func (fakeDirInfo) Size() int64        { return 0 }
func (fakeDirInfo) Mode() os.FileMode  { return 0755 }
