package godoc

import (
	"bytes"
	"go/build"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"runtime"
	"testing"
	"text/template"

	"llvm.org/llgo/third_party/go.tools/godoc/vfs"
	"llvm.org/llgo/third_party/go.tools/godoc/vfs/mapfs"
)

// setupGoroot creates temporary directory to act as GOROOT when running tests
// that depend upon the build package.  It updates build.Default to point to the
// new GOROOT.
// It returns a function that can be called to reset build.Default and remove
// the temporary directory.
func setupGoroot(t *testing.T) (cleanup func()) {
	var stdLib = map[string]string{
		"src/fmt/fmt.go": `// Package fmt implements formatted I/O.
package fmt

type Stringer interface {
	String() string
}
`,
	}
	goroot, err := ioutil.TempDir("", "cmdline_test")
	if err != nil {
		t.Fatal(err)
	}
	origContext := build.Default
	build.Default = build.Context{
		GOROOT:   goroot,
		Compiler: "gc",
	}
	for relname, contents := range stdLib {
		name := filepath.Join(goroot, relname)
		if err := os.MkdirAll(filepath.Dir(name), 0770); err != nil {
			t.Fatal(err)
		}
		if err := ioutil.WriteFile(name, []byte(contents), 0770); err != nil {
			t.Fatal(err)
		}
	}

	return func() {
		if err := os.RemoveAll(goroot); err != nil {
			t.Log(err)
		}
		build.Default = origContext
	}
}

func TestPaths(t *testing.T) {
	cleanup := setupGoroot(t)
	defer cleanup()

	pres := &Presentation{
		pkgHandler: handlerServer{
			fsRoot: "/fsroot",
		},
	}
	fs := make(vfs.NameSpace)

	absPath := "/foo/fmt"
	if runtime.GOOS == "windows" {
		absPath = `c:\foo\fmt`
	}

	for _, tc := range []struct {
		desc   string
		path   string
		expAbs string
		expRel string
	}{
		{
			"Absolute path",
			absPath,
			"/target",
			"/target",
		},
		{
			"Local import",
			"../foo/fmt",
			"/target",
			"/target",
		},
		{
			"Import",
			"fmt",
			"/target",
			"fmt",
		},
		{
			"Default",
			"unknownpkg",
			"/fsroot/unknownpkg",
			"unknownpkg",
		},
	} {
		abs, rel := paths(fs, pres, tc.path)
		if abs != tc.expAbs || rel != tc.expRel {
			t.Errorf("%s: paths(%q) = %s,%s; want %s,%s", tc.desc, tc.path, abs, rel, tc.expAbs, tc.expRel)
		}
	}
}

func TestMakeRx(t *testing.T) {
	for _, tc := range []struct {
		desc  string
		names []string
		exp   string
	}{
		{
			desc:  "empty string",
			names: []string{""},
			exp:   `^$`,
		},
		{
			desc:  "simple text",
			names: []string{"a"},
			exp:   `^a$`,
		},
		{
			desc:  "two words",
			names: []string{"foo", "bar"},
			exp:   `^foo$|^bar$`,
		},
		{
			desc:  "word & non-trivial",
			names: []string{"foo", `ab?c`},
			exp:   `^foo$|ab?c`,
		},
		{
			desc:  "bad regexp",
			names: []string{`(."`},
			exp:   `(."`,
		},
	} {
		expRE, expErr := regexp.Compile(tc.exp)
		if re, err := makeRx(tc.names); !reflect.DeepEqual(err, expErr) && !reflect.DeepEqual(re, expRE) {
			t.Errorf("%s: makeRx(%v) = %q,%q; want %q,%q", tc.desc, tc.names, re, err, expRE, expErr)
		}
	}
}

func TestCommandLine(t *testing.T) {
	cleanup := setupGoroot(t)
	defer cleanup()
	mfs := mapfs.New(map[string]string{
		"src/bar/bar.go": `// Package bar is an example.
package bar
`,
		"src/foo/foo.go": `// Package foo.
package foo

// First function is first.
func First() {
}

// Second function is second.
func Second() {
}
`,
		"src/gen/gen.go": `// Package gen
package gen

//line notgen.go:3
// F doc //line 1 should appear
// line 2 should appear
func F()
//line foo.go:100`, // no newline on end to check corner cases!
		"src/vet/vet.go": `// Package vet
package vet
`,
		"src/cmd/go/doc.go": `// The go command
package main
`,
		"src/cmd/gofmt/doc.go": `// The gofmt command
package main
`,
		"src/cmd/vet/vet.go": `// The vet command
package main
`,
	})
	fs := make(vfs.NameSpace)
	fs.Bind("/", mfs, "/", vfs.BindReplace)
	c := NewCorpus(fs)
	p := &Presentation{Corpus: c}
	p.cmdHandler = handlerServer{
		p:       p,
		c:       c,
		pattern: "/cmd/",
		fsRoot:  "/src/cmd",
	}
	p.pkgHandler = handlerServer{
		p:       p,
		c:       c,
		pattern: "/pkg/",
		fsRoot:  "/src",
		exclude: []string{"/src/cmd"},
	}
	p.initFuncMap()
	p.PackageText = template.Must(template.New("PackageText").Funcs(p.FuncMap()).Parse(`{{$info := .}}{{$filtered := .IsFiltered}}{{if $filtered}}{{range .PAst}}{{range .Decls}}{{node $info .}}{{end}}{{end}}{{else}}{{with .PAst}}{{range $filename, $ast := .}}{{$filename}}:
{{node $ $ast}}{{end}}{{end}}{{end}}{{with .PDoc}}{{if $.IsMain}}COMMAND {{.Doc}}{{else}}PACKAGE {{.Doc}}{{end}}{{with .Funcs}}
{{range .}}{{node $ .Decl}}
{{comment_text .Doc "    " "\t"}}{{end}}{{end}}{{end}}`))

	for _, tc := range []struct {
		desc string
		args []string
		exp  string
		err  bool
	}{
		{
			desc: "standard package",
			args: []string{"fmt"},
			exp:  "PACKAGE Package fmt implements formatted I/O.\n",
		},
		{
			desc: "package",
			args: []string{"bar"},
			exp:  "PACKAGE Package bar is an example.\n",
		},
		{
			desc: "package w. filter",
			args: []string{"foo", "First"},
			exp:  "PACKAGE \nfunc First()\n    First function is first.\n",
		},
		{
			desc: "package w. bad filter",
			args: []string{"foo", "DNE"},
			exp:  "PACKAGE ",
		},
		{
			desc: "source mode",
			args: []string{"src/bar"},
			exp:  "bar/bar.go:\n// Package bar is an example.\npackage bar\n",
		},
		{
			desc: "source mode w. filter",
			args: []string{"src/foo", "Second"},
			exp:  "// Second function is second.\nfunc Second() {\n}",
		},
		{
			desc: "package w. //line comments",
			args: []string{"gen", "F"},
			exp:  "PACKAGE \nfunc F()\n    F doc //line 1 should appear line 2 should appear\n",
		},
		{
			desc: "command",
			args: []string{"go"},
			exp:  "COMMAND The go command\n",
		},
		{
			desc: "forced command",
			args: []string{"cmd/gofmt"},
			exp:  "COMMAND The gofmt command\n",
		},
		{
			desc: "bad arg",
			args: []string{"doesnotexist"},
			err:  true,
		},
		{
			desc: "both command and package",
			args: []string{"vet"},
			exp:  "use 'godoc cmd/vet' for documentation on the vet command \n\nPACKAGE Package vet\n",
		},
		{
			desc: "root directory",
			args: []string{"/"},
			exp:  "",
		},
	} {
		w := new(bytes.Buffer)
		err := CommandLine(w, fs, p, tc.args)
		if got, want := w.String(), tc.exp; got != want || tc.err == (err == nil) {
			t.Errorf("%s: CommandLine(%v) = %q (%v); want %q (%v)",
				tc.desc, tc.args, got, err, want, tc.err)
		}
	}
}
