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

// Package doc extracts source code documentation from a Go AST.
package doc

import (
	"fmt"
	"go/ast"
	"go/doc/comment"
	"go/token"
	"strings"
)

// Package is the documentation for an entire package.
type Package struct {
	Doc        string
	Name       string
	ImportPath string
	Imports    []string
	Filenames  []string
	Notes      map[string][]*Note

	// Deprecated: For backward compatibility Bugs is still populated,
	// but all new code should use Notes instead.
	Bugs []string

	// declarations
	Consts []*Value
	Types  []*Type
	Vars   []*Value
	Funcs  []*Func

	// Examples is a sorted list of examples associated with
	// the package. Examples are extracted from _test.go files
	// provided to NewFromFiles.
	Examples []*Example

	importByName map[string]string
	syms         map[string]bool
}

// Value is the documentation for a (possibly grouped) var or const declaration.
type Value struct {
	Doc   string
	Names []string // var or const names in declaration order
	Decl  *ast.GenDecl

	order int
}

// Type is the documentation for a type declaration.
type Type struct {
	Doc  string
	Name string
	Decl *ast.GenDecl

	// associated declarations
	Consts  []*Value // sorted list of constants of (mostly) this type
	Vars    []*Value // sorted list of variables of (mostly) this type
	Funcs   []*Func  // sorted list of functions returning this type
	Methods []*Func  // sorted list of methods (including embedded ones) of this type

	// Examples is a sorted list of examples associated with
	// this type. Examples are extracted from _test.go files
	// provided to NewFromFiles.
	Examples []*Example
}

// Func is the documentation for a func declaration.
type Func struct {
	Doc  string
	Name string
	Decl *ast.FuncDecl

	// methods
	// (for functions, these fields have the respective zero value)
	Recv  string // actual   receiver "T" or "*T" possibly followed by type parameters [P1, ..., Pn]
	Orig  string // original receiver "T" or "*T"
	Level int    // embedding level; 0 means not embedded

	// Examples is a sorted list of examples associated with this
	// function or method. Examples are extracted from _test.go files
	// provided to NewFromFiles.
	Examples []*Example
}

// A Note represents a marked comment starting with "MARKER(uid): note body".
// Any note with a marker of 2 or more upper case [A-Z] letters and a uid of
// at least one character is recognized. The ":" following the uid is optional.
// Notes are collected in the Package.Notes map indexed by the notes marker.
type Note struct {
	Pos, End token.Pos // position range of the comment containing the marker
	UID      string    // uid found with the marker
	Body     string    // note body text
}

// Mode values control the operation of [New] and [NewFromFiles].
type Mode int

const (
	// AllDecls says to extract documentation for all package-level
	// declarations, not just exported ones.
	AllDecls Mode = 1 << iota

	// AllMethods says to show all embedded methods, not just the ones of
	// invisible (unexported) anonymous fields.
	AllMethods

	// PreserveAST says to leave the AST unmodified. Originally, pieces of
	// the AST such as function bodies were nil-ed out to save memory in
	// godoc, but not all programs want that behavior.
	PreserveAST
)

// New computes the package documentation for the given package AST.
// New takes ownership of the AST pkg and may edit or overwrite it.
// To have the [Examples] fields populated, use [NewFromFiles] and include
// the package's _test.go files.
func New(pkg *ast.Package, importPath string, mode Mode) *Package {
	var r reader
	r.readPackage(pkg, mode)
	r.computeMethodSets()
	r.cleanupTypes()
	p := &Package{
		Doc:        r.doc,
		Name:       pkg.Name,
		ImportPath: importPath,
		Imports:    sortedKeys(r.imports),
		Filenames:  r.filenames,
		Notes:      r.notes,
		Bugs:       noteBodies(r.notes["BUG"]),
		Consts:     sortedValues(r.values, token.CONST),
		Types:      sortedTypes(r.types, mode&AllMethods != 0),
		Vars:       sortedValues(r.values, token.VAR),
		Funcs:      sortedFuncs(r.funcs, true),

		importByName: r.importByName,
		syms:         make(map[string]bool),
	}

	p.collectValues(p.Consts)
	p.collectValues(p.Vars)
	p.collectTypes(p.Types)
	p.collectFuncs(p.Funcs)

	return p
}

func (p *Package) collectValues(values []*Value) {
	for _, v := range values {
		for _, name := range v.Names {
			p.syms[name] = true
		}
	}
}

func (p *Package) collectTypes(types []*Type) {
	for _, t := range types {
		if p.syms[t.Name] {
			// Shouldn't be any cycles but stop just in case.
			continue
		}
		p.syms[t.Name] = true
		p.collectValues(t.Consts)
		p.collectValues(t.Vars)
		p.collectFuncs(t.Funcs)
		p.collectFuncs(t.Methods)
		p.collectInterfaceMethods(t)
	}
}

func (p *Package) collectFuncs(funcs []*Func) {
	for _, f := range funcs {
		if f.Recv != "" {
			r := strings.TrimPrefix(f.Recv, "*")
			if i := strings.IndexByte(r, '['); i >= 0 {
				r = r[:i] // remove type parameters
			}
			p.syms[r+"."+f.Name] = true
		} else {
			p.syms[f.Name] = true
		}
	}
}

// collectInterfaceMethods adds methods of interface types within t to p.syms.
// Note that t.Methods will contain methods of non-interface types, but not interface types.
// Adding interface methods to t.Methods might make sense, but would cause us to
// include those methods in the documentation index. Adding interface methods to p.syms
// here allows us to linkify references like [io.Reader.Read] without making any other
// changes to the documentation formatting at this time.
//
// If we do start adding interface methods to t.Methods in the future,
// collectInterfaceMethods can be dropped as redundant with collectFuncs(t.Methods).
func (p *Package) collectInterfaceMethods(t *Type) {
	for _, s := range t.Decl.Specs {
		spec, ok := s.(*ast.TypeSpec)
		if !ok {
			continue
		}
		list, isStruct := fields(spec.Type)
		if isStruct {
			continue
		}
		for _, field := range list {
			for _, name := range field.Names {
				p.syms[t.Name+"."+name.Name] = true
			}
		}
	}
}

// NewFromFiles computes documentation for a package.
//
// The package is specified by a list of *ast.Files and corresponding
// file set, which must not be nil.
//
// NewFromFiles uses all provided files when computing documentation,
// so it is the caller's responsibility to provide only the files that
// match the desired build context. "go/build".Context.MatchFile can
// be used for determining whether a file matches a build context with
// the desired GOOS and GOARCH values, and other build constraints.
// The import path of the package is specified by importPath.
//
// Examples found in _test.go files are associated with the corresponding
// type, function, method, or the package, based on their name.
// If the example has a suffix in its name, it is set in the
// [Example.Suffix] field. [Examples] with malformed names are skipped.
//
// Optionally, a single extra argument of type [Mode] can be provided to
// control low-level aspects of the documentation extraction behavior.
//
// NewFromFiles takes ownership of the AST files and may edit them,
// unless the PreserveAST Mode bit is on.
func NewFromFiles(fset *token.FileSet, files []*ast.File, importPath string, opts ...any) (*Package, error) {
	// Check for invalid API usage.
	if fset == nil {
		panic(fmt.Errorf("doc.NewFromFiles: no token.FileSet provided (fset == nil)"))
	}
	var mode Mode
	switch len(opts) { // There can only be 0 or 1 options, so a simple switch works for now.
	case 0:
		// Nothing to do.
	case 1:
		m, ok := opts[0].(Mode)
		if !ok {
			panic(fmt.Errorf("doc.NewFromFiles: option argument type must be doc.Mode"))
		}
		mode = m
	default:
		panic(fmt.Errorf("doc.NewFromFiles: there must not be more than 1 option argument"))
	}

	// Collect .go and _test.go files.
	var (
		pkgName     string
		goFiles     = make(map[string]*ast.File)
		testGoFiles []*ast.File
	)
	for i, file := range files {
		f := fset.File(file.Pos())
		if f == nil {
			return nil, fmt.Errorf("file files[%d] is not found in the provided file set", i)
		}
		switch filename := f.Name(); {
		case strings.HasSuffix(filename, "_test.go"):
			testGoFiles = append(testGoFiles, file)
		case strings.HasSuffix(filename, ".go"):
			pkgName = file.Name.Name
			goFiles[filename] = file
		default:
			return nil, fmt.Errorf("file files[%d] filename %q does not have a .go extension", i, filename)
		}
	}

	// Compute package documentation.
	//
	// Since this package doesn't need Package.{Scope,Imports}, or
	// handle errors, and ast.File's Scope field is unset in files
	// parsed with parser.SkipObjectResolution, we construct the
	// Package directly instead of calling [ast.NewPackage].
	pkg := &ast.Package{Name: pkgName, Files: goFiles}
	p := New(pkg, importPath, mode)
	classifyExamples(p, Examples(testGoFiles...))
	return p, nil
}

// lookupSym reports whether the package has a given symbol or method.
//
// If recv == "", HasSym reports whether the package has a top-level
// const, func, type, or var named name.
//
// If recv != "", HasSym reports whether the package has a type
// named recv with a method named name.
func (p *Package) lookupSym(recv, name string) bool {
	if recv != "" {
		return p.syms[recv+"."+name]
	}
	return p.syms[name]
}

// lookupPackage returns the import path identified by name
// in the given package. If name uniquely identifies a single import,
// then lookupPackage returns that import.
// If multiple packages are imported as name, importPath returns "", false.
// Otherwise, if name is the name of p itself, importPath returns "", true,
// to signal a reference to p.
// Otherwise, importPath returns "", false.
func (p *Package) lookupPackage(name string) (importPath string, ok bool) {
	if path, ok := p.importByName[name]; ok {
		if path == "" {
			return "", false // multiple imports used the name
		}
		return path, true // found import
	}
	if p.Name == name {
		return "", true // allow reference to this package
	}
	return "", false // unknown name
}

// Parser returns a doc comment parser configured
// for parsing doc comments from package p.
// Each call returns a new parser, so that the caller may
// customize it before use.
func (p *Package) Parser() *comment.Parser {
	return &comment.Parser{
		LookupPackage: p.lookupPackage,
		LookupSym:     p.lookupSym,
	}
}

// Printer returns a doc comment printer configured
// for printing doc comments from package p.
// Each call returns a new printer, so that the caller may
// customize it before use.
func (p *Package) Printer() *comment.Printer {
	// No customization today, but having p.Printer()
	// gives us flexibility in the future, and it is convenient for callers.
	return &comment.Printer{}
}

// HTML returns formatted HTML for the doc comment text.
//
// To customize details of the HTML, use [Package.Printer]
// to obtain a [comment.Printer], and configure it
// before calling its HTML method.
func (p *Package) HTML(text string) []byte {
	return p.Printer().HTML(p.Parser().Parse(text))
}

// Markdown returns formatted Markdown for the doc comment text.
//
// To customize details of the Markdown, use [Package.Printer]
// to obtain a [comment.Printer], and configure it
// before calling its Markdown method.
func (p *Package) Markdown(text string) []byte {
	return p.Printer().Markdown(p.Parser().Parse(text))
}

// Text returns formatted text for the doc comment text,
// wrapped to 80 Unicode code points and using tabs for
// code block indentation.
//
// To customize details of the formatting, use [Package.Printer]
// to obtain a [comment.Printer], and configure it
// before calling its Text method.
func (p *Package) Text(text string) []byte {
	return p.Printer().Text(p.Parser().Parse(text))
}
