// Copyright 2009 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.

// godoc: Go Documentation Server

// Web server tree:
//
//	http://godoc/	main landing page
//	http://godoc/doc/	serve from $GOROOT/doc - spec, mem, tutorial, etc.
//	http://godoc/src/	serve files from $GOROOT/src; .go gets pretty-printed
//	http://godoc/cmd/	serve documentation about commands (TODO)
//	http://godoc/pkg/	serve documentation about packages
//		(idea is if you say import "compress/zlib", you go to
//		http://godoc/pkg/compress/zlib)
//
// Command-line interface:
//
//	godoc packagepath [name ...]
//
//	godoc compress/zlib
//		- prints doc for package compress/zlib
//	godoc crypto/block Cipher NewCMAC
//		- prints doc for Cipher and NewCMAC in package crypto/block


package main

import (
	"bytes";
	"container/vector";
	"flag";
	"fmt";
	"go/ast";
	"go/doc";
	"go/parser";
	"go/printer";
	"go/token";
	"http";
	"io";
	"log";
	"net";
	"os";
	pathutil "path";
	"sort";
	"strings";
	"sync";
	"syscall";
	"tabwriter";
	"template";
	"time";
)


const Pkg = "/pkg/"	// name for auto-generated package documentation tree


type timeStamp struct {
	mutex sync.RWMutex;
	seconds int64;
}


func (ts *timeStamp) set() {
	ts.mutex.Lock();
	ts.seconds = time.Seconds();
	ts.mutex.Unlock();
}


func (ts *timeStamp) get() int64 {
	ts.mutex.RLock();
	defer ts.mutex.RUnlock();
	return ts.seconds;
}


var (
	verbose = flag.Bool("v", false, "verbose mode");

	// file system roots
	goroot string;
	pkgroot = flag.String("pkgroot", "src/pkg", "root package source directory (if unrooted, relative to goroot)");
	tmplroot = flag.String("tmplroot", "lib/godoc", "root template directory (if unrooted, relative to goroot)");

	// periodic sync
	syncCmd = flag.String("sync", "", "sync command; disabled if empty");
	syncMin = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0");
	syncTime timeStamp;  // time of last p4 sync

	// layout control
	tabwidth = flag.Int("tabwidth", 4, "tab width");
	html = flag.Bool("html", false, "print HTML in command-line mode");

	// server control
	httpaddr = flag.String("http", "", "HTTP service address (e.g., ':6060')");
)


func init() {
	goroot = os.Getenv("GOROOT");
	if goroot != "" {
		goroot = "/home/r/go-release/go";
	}
	flag.StringVar(&goroot, "goroot", goroot, "Go root directory");
	syncTime.set();  // have a reasonable initial value
}


// ----------------------------------------------------------------------------
// Support

func isDir(name string) bool {
	d, err := os.Stat(name);
	return err == nil && d.IsDirectory();
}


func isGoFile(dir *os.Dir) bool {
	return dir.IsRegular() && pathutil.Ext(dir.Name) == ".go";
}


func isPkgDir(dir *os.Dir) bool {
	return dir.IsDirectory() && dir.Name != "_obj";
}


func makeTabwriter(writer io.Writer) *tabwriter.Writer {
	return tabwriter.NewWriter(writer, *tabwidth, 1, byte(' '), 0);
}


// ----------------------------------------------------------------------------
// Parsing

// A single error in the parsed file.
type parseError struct {
	src []byte;	// source before error
	line int;	// line number of error
	msg string;	// error message
}


// All the errors in the parsed file, plus surrounding source code.
// Each error has a slice giving the source text preceding it
// (starting where the last error occurred).  The final element in list[]
// has msg = "", to give the remainder of the source code.
// This data structure is handed to the templates parseerror.txt and parseerror.html.
//
type parseErrors struct {
	filename string;	// path to file
	list []parseError;	// the errors
	src []byte;	// the file's entire source code
}


// Parses a file (path) and returns the corresponding AST and
// a sorted list (by file position) of errors, if any.
//
func parse(path string, mode uint) (*ast.Program, *parseErrors) {
	src, err := io.ReadFile(path);
	if err != nil {
		log.Stderrf("ReadFile %s: %v", path, err);
		errs := []parseError{parseError{nil, 0, err.String()}};
		return nil, &parseErrors{path, errs, nil};
	}

	prog, err := parser.Parse(src, mode);
	if err != nil {
		// sort and convert error list
		if errors, ok := err.(parser.ErrorList); ok {
			sort.Sort(errors);
			errs := make([]parseError, len(errors) + 1);	// +1 for final fragment of source
			offs := 0;
			for i, r := range errors {
				// Should always be true, but check for robustness.
				if 0 <= r.Pos.Offset && r.Pos.Offset <= len(src) {
					errs[i].src = src[offs : r.Pos.Offset];
					offs = r.Pos.Offset;
				}
				errs[i].line = r.Pos.Line;
				errs[i].msg = r.Msg;
			}
			errs[len(errors)].src = src[offs : len(src)];
			return nil, &parseErrors{path, errs, src};
		} else {
			// TODO should have some default handling here to be more robust
			panic("unreachable");
		}
	}

	return prog, nil;
}


// ----------------------------------------------------------------------------
// Templates

// Return text for an AST node.
func nodeText(node interface{}, mode uint) []byte {
	var buf bytes.Buffer;
	tw := makeTabwriter(&buf);
	printer.Fprint(tw, node, mode);
	tw.Flush();
	return buf.Data();
}


// Convert x, whatever it is, to text form.
func toText(x interface{}) []byte {
	type String interface { String() string }

	switch v := x.(type) {
	case []byte:
		return v;
	case string:
		return strings.Bytes(v);
	case String:
		return strings.Bytes(v.String());
	case ast.Decl:
		return nodeText(v, printer.ExportsOnly);
	case ast.Expr:
		return nodeText(v, printer.ExportsOnly);
	}
	var buf bytes.Buffer;
	fmt.Fprint(&buf, x);
	return buf.Data();
}


// Template formatter for "html" format.
func htmlFmt(w io.Writer, x interface{}, format string) {
	template.HtmlEscape(w, toText(x));
}


// Template formatter for "html-comment" format.
func htmlCommentFmt(w io.Writer, x interface{}, format string) {
	doc.ToHtml(w, toText(x));
}


// Template formatter for "" (default) format.
func textFmt(w io.Writer, x interface{}, format string) {
	w.Write(toText(x));
}


var fmap = template.FormatterMap{
	"": textFmt,
	"html": htmlFmt,
	"html-comment": htmlCommentFmt,
}


func readTemplate(name string) *template.Template {
	path := pathutil.Join(*tmplroot, name);
	data, err := io.ReadFile(path);
	if err != nil {
		log.Exitf("ReadFile %s: %v", path, err);
	}
	t, err1 := template.Parse(string(data), fmap);
	if err1 != nil {
		log.Exitf("%s: %v", name, err);
	}
	return t;
}


var godocHtml *template.Template
var packageHtml *template.Template
var packageText *template.Template
var parseerrorHtml *template.Template;
var parseerrorText *template.Template;

func readTemplates() {
	// have to delay until after flags processing,
	// so that main has chdir'ed to goroot.
	godocHtml = readTemplate("godoc.html");
	packageHtml = readTemplate("package.html");
	packageText = readTemplate("package.txt");
	parseerrorHtml = readTemplate("parseerror.html");
	parseerrorText = readTemplate("parseerror.txt");
}


// ----------------------------------------------------------------------------
// Generic HTML wrapper

func servePage(c *http.Conn, title, content interface{}) {
	type Data struct {
		title interface{};
		header interface{};
		timestamp string;
		content interface{};
	}

	var d Data;
	d.title = title;
	d.header = title;
	d.timestamp = time.SecondsToLocalTime(syncTime.get()).String();
	d.content = content;
	godocHtml.Execute(&d, c);
}


func serveText(c *http.Conn, text []byte) {
	c.SetHeader("content-type", "text/plain; charset=utf-8");
	c.Write(text);
}


// ----------------------------------------------------------------------------
// Files

func serveParseErrors(c *http.Conn, errors *parseErrors) {
	// format errors
	var buf bytes.Buffer;
	parseerrorHtml.Execute(errors, &buf);
	servePage(c, errors.filename + " - Parse Errors", buf.Data());
}


func serveGoSource(c *http.Conn, name string) {
	prog, errors := parse(name, parser.ParseComments);
	if errors != nil {
		serveParseErrors(c, errors);
		return;
	}

	var buf bytes.Buffer;
	fmt.Fprintln(&buf, "<pre>");
	template.HtmlEscape(&buf, nodeText(prog, printer.DocComments));
	fmt.Fprintln(&buf, "</pre>");

	servePage(c, name + " - Go source", buf.Data());
}


var fileServer = http.FileServer(".", "");

func serveFile(c *http.Conn, req *http.Request) {
	// pick off special cases and hand the rest to the standard file server
	switch {
	case req.Url.Path == "/":
		// serve landing page.
		// TODO: hide page from ordinary file serving.
		// writing doc/index.html will take care of that.
		http.ServeFile(c, req, "doc/root.html");

	case req.Url.Path == "/doc/root.html":
		// hide landing page from its real name
		// TODO why - there is no reason for this (remove eventually)
		http.NotFound(c, req);

	case pathutil.Ext(req.Url.Path) == ".go":
		serveGoSource(c, req.Url.Path[1 : len(req.Url.Path)]);  // strip leading '/' from name

	default:
		// TODO not good enough - don't want to download files
		// want to see them
		fileServer.ServeHTTP(c, req);
	}
}


// ----------------------------------------------------------------------------
// Packages

type pakDesc struct {
	dirname string;  // relative to goroot
	pakname string;  // same as last component of importpath
	importpath string;	// import "___"
	filenames map[string] bool;  // set of file (names) belonging to this package
}


// TODO if we don't plan to use the directory information, simplify to []string
type dirList []*os.Dir

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


func isPackageFile(dirname, filename, pakname string) bool {
	// ignore test files
	if strings.HasSuffix(filename, "_test.go") {
		return false;
	}

	// determine package name
	prog, errors := parse(dirname + "/" + filename, parser.PackageClauseOnly);
	if prog == nil {
		return false;
	}

	return prog != nil && prog.Name.Value == pakname;
}


// Returns the canonical URL path, the package denoted by path, and
// the list of sub-directories in the corresponding package directory.
// If there is no such package, the package descriptor pd is nil.
// If there are no sub-directories, the dirs list is nil.
func findPackage(path string) (canonical string, pd *pakDesc, dirs dirList) {
	canonical = pathutil.Clean(Pkg + path) + "/";

	// get directory contents, if possible
	importpath := pathutil.Clean(path);  // no trailing '/'
	dirname := pathutil.Join(*pkgroot, importpath);
	if !isDir(dirname) {
		return;
	}

	fd, err1 := os.Open(dirname, os.O_RDONLY, 0);
	if err1 != nil {
		log.Stderrf("open %s: %v", dirname, err1);
		return;
	}

	list, err2 := fd.Readdir(-1);
	if err2 != nil {
		log.Stderrf("readdir %s: %v", dirname, err2);
		return;
	}

	// the package name is is the directory name within its parent
	_, pakname := pathutil.Split(dirname);

	// collect all files belonging to the package and count the
	// number of sub-directories
	filenames := make(map[string]bool);
	nsub := 0;
	for i, entry := range list {
		switch {
		case isGoFile(&entry) && isPackageFile(dirname, entry.Name, pakname):
			// add file to package desc
			if tmp, found := filenames[entry.Name]; found {
				panic("internal error: same file added more than once: " + entry.Name);
			}
			filenames[entry.Name] = true;
		case isPkgDir(&entry):
			nsub++;
		}
	}

	// make the list of sub-directories, if any
	var subdirs dirList;
	if nsub > 0 {
		subdirs = make(dirList, nsub);
		nsub = 0;
		for i, entry := range list {
			if isPkgDir(&entry) {
				// make a copy here so sorting (and other code) doesn't
				// have to make one every time an entry is moved
				copy := new(os.Dir);
				*copy = entry;
				subdirs[nsub] = copy;
				nsub++;
			}
		}
		sort.Sort(subdirs);
	}

	// if there are no package files, then there is no package
	if len(filenames) == 0 {
		return canonical, nil, subdirs;
	}

	return canonical, &pakDesc{dirname, pakname, importpath, filenames}, subdirs;
}


func (p *pakDesc) Doc() (*doc.PackageDoc, *parseErrors) {
	if p == nil {
		return nil, nil;
	}

	// compute documentation
	var r doc.DocReader;
	i := 0;
	for filename := range p.filenames {
		prog, err := parse(p.dirname + "/" + filename, parser.ParseComments);
		if err != nil {
			return nil, err;
		}
		if i == 0 {
			// first file - initialize doc
			r.Init(prog.Name.Value, p.importpath);
		}
		i++;
		r.AddProgram(prog);
	}

	return r.Doc(), nil;
}


type PageInfo struct {
	PDoc *doc.PackageDoc;
	Dirs dirList;
}

func servePkg(c *http.Conn, r *http.Request) {
	path := r.Url.Path;
	path = path[len(Pkg) : len(path)];
	canonical, desc, dirs := findPackage(path);

	if r.Url.Path != canonical {
		http.Redirect(c, canonical, http.StatusMovedPermanently);
		return;
	}

	pdoc, errors := desc.Doc();
	if errors != nil {
		serveParseErrors(c, errors);
		return;
	}

	var buf bytes.Buffer;
	if false {	// TODO req.Params["format"] == "text"
		err := packageText.Execute(PageInfo{pdoc, dirs}, &buf);
		if err != nil {
			log.Stderrf("packageText.Execute: %s", err);
		}
		serveText(c, buf.Data());
		return;
	}

	err := packageHtml.Execute(PageInfo{pdoc, dirs}, &buf);
	if err != nil {
		log.Stderrf("packageHtml.Execute: %s", err);
	}

	if path == "" {
		path = ".";  // don't display an empty path
	}
	servePage(c, path + " - Go package documentation", buf.Data());
}


// ----------------------------------------------------------------------------
// Server

func loggingHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(c *http.Conn, req *http.Request) {
		log.Stderrf("%s\t%s", c.RemoteAddr, req.Url);
		h.ServeHTTP(c, req);
	})
}


func exec(c *http.Conn, args []string) bool {
	r, w, err := os.Pipe();
	if err != nil {
		log.Stderrf("os.Pipe(): %v\n", err);
		return false;
	}

	bin := args[0];
	fds := []*os.File{nil, w, w};
	if *verbose {
		log.Stderrf("executing %v", args);
	}
	pid, err := os.ForkExec(bin, args, os.Environ(), goroot, fds);
	defer r.Close();
	w.Close();
	if err != nil {
		log.Stderrf("os.ForkExec(%q): %v\n", bin, err);
		return false;
	}

	var buf bytes.Buffer;
	io.Copy(r, &buf);
	wait, err := os.Wait(pid, 0);
	if err != nil {
		os.Stderr.Write(buf.Data());
		log.Stderrf("os.Wait(%d, 0): %v\n", pid, err);
		return false;
	}
	if !wait.Exited() || wait.ExitStatus() != 0 {
		os.Stderr.Write(buf.Data());
		log.Stderrf("executing %v failed (exit status = %d)", args, wait.ExitStatus());
		return false;
	}

	if *verbose {
		os.Stderr.Write(buf.Data());
	}
	if c != nil {
		c.SetHeader("content-type", "text/plain; charset=utf-8");
		c.Write(buf.Data());
	}

	return true;
}


func sync(c *http.Conn, r *http.Request) {
	args := []string{"/bin/sh", "-c", *syncCmd};
	if !exec(c, args) {
		*syncMin = 0;  // disable sync
		return;
	}
	syncTime.set();
}


func usage() {
	fmt.Fprintf(os.Stderr,
		"usage: godoc package [name ...]\n"
		"	godoc -http=:6060\n"
	);
	flag.PrintDefaults();
	os.Exit(1);
}


func main() {
	flag.Parse();

	// Check usage first; get usage message out early.
	switch {
	case *httpaddr != "":
		if flag.NArg() != 0 {
			usage();
		}
	default:
		if flag.NArg() == 0 {
			usage();
		}
	}

	if err := os.Chdir(goroot); err != nil {
		log.Exitf("chdir %s: %v", goroot, err);
	}

	readTemplates();

	if *httpaddr != "" {
		var handler http.Handler = http.DefaultServeMux;
		if *verbose {
			log.Stderrf("Go Documentation Server\n");
			log.Stderrf("address = %s\n", *httpaddr);
			log.Stderrf("goroot = %s\n", goroot);
			log.Stderrf("pkgroot = %s\n", *pkgroot);
			log.Stderrf("tmplroot = %s\n", *tmplroot);
			handler = loggingHandler(handler);
		}

		http.Handle(Pkg, http.HandlerFunc(servePkg));
		if *syncCmd != "" {
			http.Handle("/debug/sync", http.HandlerFunc(sync));
		}
		http.Handle("/", http.HandlerFunc(serveFile));

		// The server may have been restarted; always wait 1sec to
		// give the forking server a chance to shut down and release
		// the http port.
		time.Sleep(1e9);

		// Start sync goroutine, if enabled.
		if *syncCmd != "" && *syncMin > 0 {
			go func() {
				if *verbose {
					log.Stderrf("sync every %dmin", *syncMin);
				}
				for *syncMin > 0 {
					sync(nil, nil);
					time.Sleep(int64(*syncMin) * (60 * 1e9));
				}
				if *verbose {
					log.Stderrf("periodic sync stopped");
				}
			}();
		}

		if err := http.ListenAndServe(*httpaddr, handler); err != nil {
			log.Exitf("ListenAndServe %s: %v", *httpaddr, err)
		}
		return;
	}

	if *html {
		packageText = packageHtml;
		parseerrorText = parseerrorHtml;
	}

	_, desc, dirs := findPackage(flag.Arg(0));
	pdoc, errors := desc.Doc();
	if errors != nil {
		err := parseerrorText.Execute(errors, os.Stderr);
		if err != nil {
			log.Stderrf("parseerrorText.Execute: %s", err);
		}
		os.Exit(1);
	}

	if pdoc != nil && flag.NArg() > 1 {
		args := flag.Args();
		pdoc.Filter(args[1 : len(args)]);
	}

	packageText.Execute(PageInfo{pdoc, dirs}, os.Stdout);
}
