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

// The generate command updates the following files of documentation:
//
//	gopls/doc/settings.md   -- from linking gopls/internal/settings.DefaultOptions
//	gopls/doc/analyzers.md  -- from linking gopls/internal/settings.DefaultAnalyzers
//	gopls/doc/inlayHints.md -- from loading gopls/internal/settings.InlayHint
//	gopls/internal/doc/api.json -- all of the above in a single value, for 'gopls api-json'
//
// Run it with this command:
//
//	$ cd gopls/internal/doc/generate && go generate
package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"go/ast"
	"go/doc/comment"
	"go/token"
	"go/types"
	"maps"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"regexp"
	"slices"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode"

	goastutil "golang.org/x/tools/go/ast/astutil"
	"golang.org/x/tools/go/packages"
	"golang.org/x/tools/gopls/internal/cache"
	"golang.org/x/tools/gopls/internal/doc"
	"golang.org/x/tools/gopls/internal/golang"
	"golang.org/x/tools/gopls/internal/mod"
	"golang.org/x/tools/gopls/internal/settings"
	"golang.org/x/tools/gopls/internal/util/safetoken"
	"golang.org/x/tools/internal/astutil"
)

func main() {
	if _, err := doMain(true); err != nil {
		fmt.Fprintf(os.Stderr, "Generation failed: %v\n", err)
		os.Exit(1)
	}
}

// doMain regenerates the output files. On success:
// - if write, it updates them;
// - if !write, it reports whether they would change.
func doMain(write bool) (bool, error) {
	api, err := loadAPI()
	if err != nil {
		return false, err
	}

	goplsDir, err := pkgDir("golang.org/x/tools/gopls")
	if err != nil {
		return false, err
	}

	// TODO(adonovan): consider using HTML, not Markdown, for the
	// generated reference documents. It's not more difficult, the
	// layout is easier to read, and we can use go/doc-comment
	// rendering logic.

	for _, f := range []struct {
		name    string // relative to gopls
		rewrite rewriter
	}{
		{"internal/doc/api.json", rewriteAPI},
		{"doc/settings.md", rewriteSettings},
		{"doc/codelenses.md", rewriteCodeLenses},
		{"doc/analyzers.md", rewriteAnalyzers},
		{"doc/inlayHints.md", rewriteInlayHints},
	} {
		file := filepath.Join(goplsDir, f.name)
		old, err := os.ReadFile(file)
		if err != nil {
			return false, err
		}

		new, err := f.rewrite(old, api)
		if err != nil {
			return false, fmt.Errorf("rewriting %q: %v", file, err)
		}

		if write {
			if err := os.WriteFile(file, new, 0); err != nil {
				return false, err
			}
		} else if !bytes.Equal(old, new) {
			return false, nil // files would change
		}
	}
	return true, nil
}

// A rewriter is a function that transforms the content of a file.
type rewriter = func([]byte, *doc.API) ([]byte, error)

// pkgDir returns the directory corresponding to the import path pkgPath.
func pkgDir(pkgPath string) (string, error) {
	cmd := exec.Command("go", "list", "-f", "{{.Dir}}", pkgPath)
	out, err := cmd.Output()
	if err != nil {
		if ee, _ := err.(*exec.ExitError); ee != nil && len(ee.Stderr) > 0 {
			return "", fmt.Errorf("%v: %w\n%s", cmd, err, ee.Stderr)
		}
		return "", fmt.Errorf("%v: %w", cmd, err)
	}
	return strings.TrimSpace(string(out)), nil
}

// loadAPI computes the JSON-encodable value that describes gopls'
// interfaces, by a combination of static and dynamic analysis.
func loadAPI() (*doc.API, error) {
	pkgs, err := packages.Load(
		&packages.Config{
			Mode: packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax | packages.NeedDeps,
		},
		"golang.org/x/tools/gopls/internal/settings",
	)
	if err != nil {
		return nil, err
	}
	settingsPkg := pkgs[0]

	defaults := settings.DefaultOptions()
	api := &doc.API{
		Options:   map[string][]*doc.Option{},
		Analyzers: loadAnalyzers(settings.AllAnalyzers, defaults),
	}

	api.Lenses, err = loadLenses(settingsPkg, defaults.Codelenses)
	if err != nil {
		return nil, err
	}
	api.Hints, err = loadHints(settingsPkg)
	if err != nil {
		return nil, err
	}

	for _, category := range []reflect.Value{
		reflect.ValueOf(defaults.UserOptions),
	} {
		// Find the type information and ast.File corresponding to the category.
		optsType := settingsPkg.Types.Scope().Lookup(category.Type().Name())
		if optsType == nil {
			return nil, fmt.Errorf("could not find %v in scope %v", category.Type().Name(), settingsPkg.Types.Scope())
		}
		opts, err := loadOptions(category, optsType, settingsPkg, "")
		if err != nil {
			return nil, err
		}

		// Edge case for "analyses": populate its enum keys from
		// the analyzer list, since its map keys are strings, not enums.
		// Also, set its EnumKeys.ValueType for historical reasons.
		for _, opt := range opts {
			if opt.Name == "analyses" {
				opt.EnumKeys.ValueType = "bool"
				for _, a := range api.Analyzers {
					opt.EnumKeys.Keys = append(opt.EnumKeys.Keys, doc.EnumKey{
						Name:    fmt.Sprintf("%q", a.Name),
						Doc:     a.Doc,
						Default: strconv.FormatBool(a.Default),
					})
				}
			}
		}

		catName := strings.TrimSuffix(category.Type().Name(), "Options")
		api.Options[catName] = opts
	}
	return api, nil
}

// loadOptions computes a single category of settings by a combination
// of static analysis and reflection over gopls internal types.
func loadOptions(category reflect.Value, optsType types.Object, pkg *packages.Package, hierarchy string) ([]*doc.Option, error) {
	file, err := fileForPos(pkg, optsType.Pos())
	if err != nil {
		return nil, err
	}

	enums, err := loadEnums(pkg) // TODO(adonovan): do this only once at toplevel.
	if err != nil {
		return nil, err
	}

	var opts []*doc.Option
	optsStruct := optsType.Type().Underlying().(*types.Struct)
	for typesField := range optsStruct.Fields() {
		// The types field gives us the type.

		// If the field name ends with "Options", assume it is a struct with
		// additional options and process it recursively.
		if h, ok := strings.CutSuffix(typesField.Name(), "Options"); ok {
			// Keep track of the parent structs.
			if hierarchy != "" {
				h = hierarchy + "." + h
			}
			options, err := loadOptions(category, typesField, pkg, strings.ToLower(h))
			if err != nil {
				return nil, err
			}
			opts = append(opts, options...)
			continue
		}
		path, _ := goastutil.PathEnclosingInterval(file, typesField.Pos(), typesField.Pos())
		if len(path) < 2 {
			return nil, fmt.Errorf("could not find AST node for field %v", typesField)
		}

		// The AST field gives us the doc.
		astField, ok := path[1].(*ast.Field)
		if !ok {
			return nil, fmt.Errorf("unexpected AST path %v", path)
		}
		description, deprecation := astField.Doc.Text(), astutil.Deprecation(astField.Doc)

		// The reflect field gives us the default value.
		reflectField := category.FieldByName(typesField.Name())
		if !reflectField.IsValid() {
			return nil, fmt.Errorf("could not find reflect field for %v", typesField.Name())
		}

		def, err := formatDefault(reflectField)
		if err != nil {
			return nil, err
		}

		// Derive the doc-and-api.json type from the Go field type.
		//
		// In principle, we should use JSON nomenclature here
		// (number, array, object, etc; see #68057), but in
		// practice we use the Go type string ([]T, map[K]V,
		// etc) with only one tweak: enumeration types are
		// replaced by "enum", including when they appear as
		// map keys.
		//
		// Notable edge cases:
		// - any (e.g. in linksInHover) is really a sum of false | true | "internal".
		// - time.Duration is really a string with a particular syntax.
		typ := typesField.Type().String()
		if _, ok := enums[typesField.Type()]; ok {
			typ = "enum"
		}
		name := lowerFirst(typesField.Name())

		// enum-keyed maps
		var enumKeys doc.EnumKeys
		if m, ok := typesField.Type().Underlying().(*types.Map); ok {
			if values, ok := enums[m.Key()]; ok {
				// Update type name: "map[CodeLensSource]T" -> "map[enum]T"
				// hack: assumes key substring is unique!
				typ = strings.Replace(typ, m.Key().String(), "enum", 1)

				enumKeys.ValueType = m.Elem().String() // e.g. bool

				// For map[enum]T fields, gather the set of valid
				// EnumKeys (from type information). If T=bool, also
				// record the default value (from reflection).
				keys, err := collectEnumKeys(m, reflectField, values)
				if err != nil {
					return nil, err
				}
				enumKeys.Keys = keys
			}
		}

		// Get the status of the field by checking its struct tags.
		reflectStructField, ok := category.Type().FieldByName(typesField.Name())
		if !ok {
			return nil, fmt.Errorf("no struct field for %s", typesField.Name())
		}
		status := reflectStructField.Tag.Get("status")

		opts = append(opts, &doc.Option{
			Name:               name,
			Type:               typ,
			Doc:                lowerFirst(description),
			Default:            def,
			EnumKeys:           enumKeys,
			EnumValues:         enums[typesField.Type()],
			Status:             status,
			Hierarchy:          hierarchy,
			DeprecationMessage: lowerFirst(strings.TrimPrefix(deprecation, "Deprecated: ")),
		})
	}
	return opts, nil
}

// loadEnums returns a description of gopls' settings enum types based on static analysis.
func loadEnums(pkg *packages.Package) (map[types.Type][]doc.EnumValue, error) {
	enums := make(map[types.Type][]doc.EnumValue)
	for _, name := range pkg.Types.Scope().Names() {
		obj := pkg.Types.Scope().Lookup(name)
		cnst, ok := obj.(*types.Const)
		if !ok {
			continue
		}
		f, err := fileForPos(pkg, cnst.Pos())
		if err != nil {
			return nil, fmt.Errorf("finding file for %q: %v", cnst.Name(), err)
		}
		path, _ := goastutil.PathEnclosingInterval(f, cnst.Pos(), cnst.Pos())
		spec := path[1].(*ast.ValueSpec)
		value := cnst.Val().ExactString()
		docstring := valueDoc(cnst.Name(), value, spec.Doc.Text())
		var status string
		for _, d := range astutil.Directives(spec.Doc) {
			if d.Tool == "gopls" && d.Name == "status" {
				status = d.Args
				break
			}
		}
		v := doc.EnumValue{
			Value:  value,
			Doc:    docstring,
			Status: status,
		}
		enums[obj.Type()] = append(enums[obj.Type()], v)
	}

	// linksInHover is a one-off edge case (true | false | "gopls")
	// that doesn't warrant a general solution (e.g. struct tag).
	enums[pkg.Types.Scope().Lookup("LinksInHoverEnum").Type()] = []doc.EnumValue{
		{Value: "false", Doc: "false: do not show links"},
		{Value: "true", Doc: "true: show links to the `linkTarget` domain"},
		{Value: `"gopls"`, Doc: "`\"gopls\"`: show links to gopls' internal documentation viewer"},
	}

	return enums, nil
}

func collectEnumKeys(m *types.Map, reflectField reflect.Value, enumValues []doc.EnumValue) ([]doc.EnumKey, error) {
	// We can get default values for enum -> bool maps.
	var isEnumBoolMap bool
	if basic, ok := m.Elem().Underlying().(*types.Basic); ok && basic.Kind() == types.Bool {
		isEnumBoolMap = true
	}
	var keys []doc.EnumKey
	for _, v := range enumValues {
		var def string
		if isEnumBoolMap {
			var err error
			def, err = formatDefaultFromEnumBoolMap(reflectField, v.Value)
			if err != nil {
				return nil, err
			}
		}
		keys = append(keys, doc.EnumKey{
			Name:    v.Value,
			Doc:     v.Doc,
			Status:  v.Status,
			Default: def,
		})
	}
	return keys, nil
}

func formatDefaultFromEnumBoolMap(reflectMap reflect.Value, enumKey string) (string, error) {
	if reflectMap.Kind() != reflect.Map {
		return "", nil
	}
	name := enumKey
	if unquoted, err := strconv.Unquote(name); err == nil {
		name = unquoted
	}
	for _, e := range reflectMap.MapKeys() {
		if e.String() == name {
			value := reflectMap.MapIndex(e)
			if value.Type().Kind() == reflect.Bool {
				return formatDefault(value)
			}
		}
	}
	// Assume that if the value isn't mentioned in the map, it defaults to
	// the default value, false.
	return formatDefault(reflect.ValueOf(false))
}

// formatDefault formats the default value into a JSON-like string.
// VS Code exposes settings as JSON, so showing them as JSON is reasonable.
// TODO(rstambler): Reconsider this approach, as the VS Code Go generator now
// marshals to JSON.
func formatDefault(reflectField reflect.Value) (string, error) {
	def := reflectField.Interface()

	// Durations marshal as nanoseconds, but we want the stringy versions,
	// e.g. "100ms".
	if t, ok := def.(time.Duration); ok {
		def = t.String()
	}
	defBytes, err := json.Marshal(def)
	if err != nil {
		return "", err
	}

	// Nil values format as "null" so print them as hardcoded empty values.
	switch reflectField.Type().Kind() {
	case reflect.Map:
		if reflectField.IsNil() {
			defBytes = []byte("{}")
		}
	case reflect.Slice:
		if reflectField.IsNil() {
			defBytes = []byte("[]")
		}
	}
	return string(defBytes), err
}

// valueDoc transforms a docstring documenting a constant identifier to a
// docstring documenting its value.
//
// If doc is of the form "Foo is a bar", it returns '`"fooValue"` is a bar'. If
// doc is non-standard ("this value is a bar"), it returns '`"fooValue"`: this
// value is a bar'.
func valueDoc(name, value, doc string) string {
	if doc == "" {
		return ""
	}
	if strings.HasPrefix(doc, name) {
		// docstring in standard form. Replace the subject with value.
		return fmt.Sprintf("`%s`%s", value, doc[len(name):])
	}
	return fmt.Sprintf("`%s`: %s", value, doc)
}

// loadLenses combines the syntactic comments from the settings
// package with the default values from settings.DefaultOptions(), and
// returns a list of Code Lens descriptors.
func loadLenses(settingsPkg *packages.Package, defaults map[settings.CodeLensSource]bool) ([]*doc.Lens, error) {
	// Find the CodeLensSource enums among the files of the protocol package.
	// Map each enum value to its doc comment.
	enumDoc := make(map[string]string)
	enumStatus := make(map[string]string)
	for _, f := range settingsPkg.Syntax {
		for _, decl := range f.Decls {
			if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.CONST {
				for _, spec := range decl.Specs {
					spec := spec.(*ast.ValueSpec)
					posn := safetoken.StartPosition(settingsPkg.Fset, spec.Pos())
					if id, ok := spec.Type.(*ast.Ident); ok && id.Name == "CodeLensSource" {
						if len(spec.Names) != 1 || len(spec.Values) != 1 {
							return nil, fmt.Errorf("%s: declare one CodeLensSource per line", posn)
						}
						lit, ok := spec.Values[0].(*ast.BasicLit)
						if !ok || lit.Kind != token.STRING {
							return nil, fmt.Errorf("%s: CodeLensSource value is not a string literal", posn)
						}
						value, _ := strconv.Unquote(lit.Value) // ignore error: AST is well-formed
						if spec.Doc == nil {
							return nil, fmt.Errorf("%s: %s lacks doc comment", posn, spec.Names[0].Name)
						}
						enumDoc[value] = spec.Doc.Text()
						for _, d := range astutil.Directives(spec.Doc) {
							if d.Tool == "gopls" && d.Name == "status" {
								enumStatus[value] = d.Args
								break
							}
						}
					}
				}
			}
		}
	}
	if len(enumDoc) == 0 {
		return nil, fmt.Errorf("failed to extract any CodeLensSource declarations")
	}

	// Build list of Lens descriptors.
	var lenses []*doc.Lens
	addAll := func(sources map[settings.CodeLensSource]cache.CodeLensSourceFunc, fileType string) error {
		for _, source := range slices.Sorted(maps.Keys(sources)) {
			docText, ok := enumDoc[string(source)]
			if !ok {
				return fmt.Errorf("missing CodeLensSource declaration for %s", source)
			}
			title, docText, _ := strings.Cut(docText, "\n") // first line is title
			lenses = append(lenses, &doc.Lens{
				FileType: fileType,
				Lens:     string(source),
				Title:    title,
				Doc:      docText,
				Default:  defaults[source],
				Status:   enumStatus[string(source)],
			})
		}
		return nil
	}
	err := errors.Join(
		addAll(golang.CodeLensSources(), "Go"),
		addAll(mod.CodeLensSources(), "go.mod"))
	return lenses, err
}

func loadAnalyzers(analyzers []*settings.Analyzer, defaults *settings.Options) []*doc.Analyzer {
	slices.SortFunc(analyzers, func(x, y *settings.Analyzer) int {
		return strings.Compare(x.Analyzer().Name, y.Analyzer().Name)
	})
	var json []*doc.Analyzer
	for _, a := range analyzers {
		json = append(json, &doc.Analyzer{
			Name:    a.Analyzer().Name,
			Doc:     a.Analyzer().Doc,
			URL:     a.Analyzer().URL,
			Default: a.Enabled(defaults),
		})
	}
	return json
}

// loadHints derives and returns the inlay hints metadata from the settings.InlayHint type.
func loadHints(settingsPkg *packages.Package) ([]*doc.Hint, error) {
	enums, err := loadEnums(settingsPkg) // TODO(adonovan): call loadEnums exactly once
	if err != nil {
		return nil, err
	}
	inlayHint := settingsPkg.Types.Scope().Lookup("InlayHint").Type()
	var hints []*doc.Hint
	for _, enumVal := range enums[inlayHint] {
		name, _ := strconv.Unquote(enumVal.Value)
		hints = append(hints, &doc.Hint{
			Name:   name,
			Doc:    enumVal.Doc,
			Status: enumVal.Status,
		})
	}
	return hints, nil
}

func lowerFirst(x string) string {
	if x == "" {
		return x
	}
	return strings.ToLower(x[:1]) + x[1:]
}

func fileForPos(pkg *packages.Package, pos token.Pos) (*ast.File, error) {
	fset := pkg.Fset
	for _, f := range pkg.Syntax {
		if safetoken.StartPosition(fset, f.FileStart).Filename == safetoken.StartPosition(fset, pos).Filename {
			return f, nil
		}
	}
	return nil, fmt.Errorf("no file for pos %v", pos)
}

func rewriteAPI(_ []byte, api *doc.API) ([]byte, error) {
	return json.MarshalIndent(api, "", "\t")
}

type optionsGroup struct {
	title   string // dotted path (e.g. "ui.documentation")
	final   string // final segment of title (e.g. "documentation")
	level   int
	options []*doc.Option
}

func rewriteSettings(prevContent []byte, api *doc.API) ([]byte, error) {
	content := prevContent
	for category, opts := range api.Options {
		groups := collectGroups(opts)

		var buf bytes.Buffer

		// First, print a table of contents (ToC).
		fmt.Fprintln(&buf)
		for _, h := range groups {
			title := h.final
			if title != "" {
				fmt.Fprintf(&buf, "%s* [%s](#%s)\n",
					strings.Repeat("  ", h.level),
					capitalize(title),
					strings.ToLower(title))
			}
		}

		// Section titles are h2, options are h3.
		// This is independent of the option hierarchy.
		// (Nested options should not be smaller!)
		fmt.Fprintln(&buf)
		for _, h := range groups {
			title := h.final
			if title != "" {
				// Emit HTML anchor as GitHub markdown doesn't support
				// "# Heading {#anchor}" syntax.
				fmt.Fprintf(&buf, "<a id='%s'></a>\n", strings.ToLower(title))

				fmt.Fprintf(&buf, "## %s\n\n", capitalize(title))
			}
			for _, opt := range h.options {
				// Emit HTML anchor as GitHub markdown doesn't support
				// "# Heading {#anchor}" syntax.
				//
				// (Each option name is the camelCased name of a field of
				// settings.UserOptions or one of its FooOptions subfields.)
				fmt.Fprintf(&buf, "<a id='%s'></a>\n", opt.Name)

				// heading
				//
				// We do not display the undocumented dotted-path alias
				// (h.title + "." + opt.Name) used by VS Code only.
				fmt.Fprintf(&buf, "### `%s %s`\n\n", opt.Name, opt.Type)

				// status
				writeStatus(&buf, opt.Status)

				// doc comment
				buf.WriteString(opt.Doc)

				// enums
				write := func(name, doc string) {
					if doc != "" {
						unbroken := parBreakRE.ReplaceAllString(doc, "\\\n")
						fmt.Fprintf(&buf, "* %s\n", strings.TrimSpace(unbroken))
					} else {
						fmt.Fprintf(&buf, "* `%s`\n", name)
					}
				}
				if len(opt.EnumValues) > 0 && opt.Type == "enum" {
					// enum as top-level type constructor
					buf.WriteString("\nMust be one of:\n\n")
					for _, val := range opt.EnumValues {
						write(val.Value, val.Doc)
					}
				} else if len(opt.EnumKeys.Keys) > 0 && shouldShowEnumKeysInSettings(opt.Name) {
					// enum as map key (currently just "annotations")
					buf.WriteString("\nEach enum must be one of:\n\n")
					for _, val := range opt.EnumKeys.Keys {
						write(val.Name, val.Doc)
					}
				}

				// default value
				fmt.Fprintf(&buf, "\nDefault: `%v`.\n\n", opt.Default)
			}
		}
		newContent, err := replaceSection(content, category, buf.Bytes())
		if err != nil {
			return nil, err
		}
		content = newContent
	}
	return content, nil
}

// writeStatus emits a Markdown paragraph to buf about the status of a feature,
// if nonempty.
func writeStatus(buf *bytes.Buffer, status string) {
	switch status {
	case "":
	case "advanced":
		fmt.Fprint(buf, "**This is an advanced setting and should not be configured by most `gopls` users.**\n\n")
	case "debug":
		fmt.Fprint(buf, "**This setting is for debugging purposes only.**\n\n")
	case "experimental":
		fmt.Fprint(buf, "**This setting is experimental and may be deleted.**\n\n")
	default:
		fmt.Fprintf(buf, "**Status: %s.**\n\n", status)
	}
}

var parBreakRE = regexp.MustCompile("\n{2,}")

func shouldShowEnumKeysInSettings(name string) bool {
	// These fields have too many possible options,
	// or too voluminous documentation, to render as enums.
	// Instead they each get their own page in the manual.
	return !(name == "analyses" || name == "codelenses" || name == "hints")
}

func collectGroups(opts []*doc.Option) []optionsGroup {
	optsByHierarchy := map[string][]*doc.Option{}
	for _, opt := range opts {
		optsByHierarchy[opt.Hierarchy] = append(optsByHierarchy[opt.Hierarchy], opt)
	}

	// As a hack, assume that uncategorized items are less important to
	// users and force the empty string to the end of the list.
	var containsEmpty bool
	var sorted []string
	for h := range optsByHierarchy {
		if h == "" {
			containsEmpty = true
			continue
		}
		sorted = append(sorted, h)
	}
	sort.Strings(sorted)
	if containsEmpty {
		sorted = append(sorted, "")
	}
	var groups []optionsGroup
	baseLevel := 0
	for _, h := range sorted {
		split := strings.SplitAfter(h, ".")
		last := split[len(split)-1]
		// Hack to capitalize all of UI.
		if last == "ui" {
			last = "UI"
		}
		// A hierarchy may look like "ui.formatting". If "ui" has no
		// options of its own, it may not be added to the map, but it
		// still needs a heading.
		components := strings.Split(h, ".")
		for i := 1; i < len(components); i++ {
			parent := strings.Join(components[0:i], ".")
			if _, ok := optsByHierarchy[parent]; !ok {
				groups = append(groups, optionsGroup{
					title: parent,
					final: last,
					level: baseLevel + i,
				})
			}
		}
		groups = append(groups, optionsGroup{
			title:   h,
			final:   last,
			level:   baseLevel + strings.Count(h, "."),
			options: optsByHierarchy[h],
		})
	}
	return groups
}

func capitalize(s string) string {
	return string(unicode.ToUpper(rune(s[0]))) + s[1:]
}

func rewriteCodeLenses(prevContent []byte, api *doc.API) ([]byte, error) {
	var buf bytes.Buffer
	for _, lens := range api.Lenses {
		fmt.Fprintf(&buf, "## `%s`: %s\n\n", lens.Lens, lens.Title)
		writeStatus(&buf, lens.Status)
		fmt.Fprintf(&buf, "%s\n\n", lens.Doc)
		fmt.Fprintf(&buf, "Default: %v\n\n", onOff(lens.Default))
		fmt.Fprintf(&buf, "File type: %s\n\n", lens.FileType)
	}
	return replaceSection(prevContent, "Lenses", buf.Bytes())
}

func rewriteAnalyzers(prevContent []byte, api *doc.API) ([]byte, error) {
	var buf bytes.Buffer
	for _, analyzer := range api.Analyzers {
		fmt.Fprintf(&buf, "<a id='%s'></a>\n", analyzer.Name)
		title, doc, _ := strings.Cut(analyzer.Doc, "\n")
		title = strings.TrimPrefix(title, analyzer.Name+": ")
		fmt.Fprintf(&buf, "## `%s`: %s\n\n", analyzer.Name, title)

		// Convert Analyzer.Doc from go/doc/comment form to Markdown.
		// Headings in doc comments are converted to ### (HeadingLevel=3).
		//
		// Some Analyzers (e.g. go/analysis/passes/inline) use ## to indicate subheadings
		// Although this is valid Markdown, it is not valid go/doc/comment,
		// nor is it rendered as a subheading by pkg.go.dev or gopls's doc viewer.
		// Perhaps it will be supported in future; see
		// https://github.com/golang/go/issues/51082#issuecomment-1033116430 et seq.
		//
		// In the meantime, the go/doc/comment processing will escape them so
		// that the ## appears literally in analyzers.md just as it does in
		// the two viewers mentioned above. The meaning is clear enough.
		doctree := new(comment.Parser).Parse(doc)
		buf.Write((&comment.Printer{HeadingLevel: 3}).Markdown(doctree))
		buf.WriteString("\n\n")

		fmt.Fprintf(&buf, "Default: %s.", onOff(analyzer.Default))
		if !analyzer.Default {
			fmt.Fprintf(&buf, " Enable by setting `\"analyses\": {\"%s\": true}`.", analyzer.Name)
		}
		fmt.Fprintf(&buf, "\n\n")
		if analyzer.URL != "" {
			// TODO(adonovan): currently the URL provides the same information
			// as 'doc' above, though that may change due to
			// https://github.com/golang/go/issues/61315#issuecomment-1841350181.
			// In that case, update this to something like "Complete documentation".
			fmt.Fprintf(&buf, "Package documentation: [%s](%s)\n\n",
				analyzer.Name, analyzer.URL)
		}

	}
	return replaceSection(prevContent, "Analyzers", buf.Bytes())
}

func rewriteInlayHints(prevContent []byte, api *doc.API) ([]byte, error) {
	var buf bytes.Buffer
	for _, hint := range api.Hints {
		fmt.Fprintf(&buf, "## **%v**\n\n", hint.Name)
		fmt.Fprintf(&buf, "%s\n\n", hint.Doc)
		switch hint.Default {
		case true:
			fmt.Fprintf(&buf, "**Enabled by default.**\n\n")
		case false:
			fmt.Fprintf(&buf, "**Disabled by default. Enable it by setting `\"hints\": {\"%s\": true}`.**\n\n", hint.Name)
		}
	}
	return replaceSection(prevContent, "Hints", buf.Bytes())
}

// replaceSection replaces the portion of a file delimited by comments of the form:
//
//	<!-- BEGIN sectionName -->
//	<!-- END section Name -->
func replaceSection(content []byte, sectionName string, replacement []byte) ([]byte, error) {
	re := regexp.MustCompile(fmt.Sprintf(`(?s)<!-- BEGIN %v.* -->\n(.*?)<!-- END %v.* -->`, sectionName, sectionName))
	idx := re.FindSubmatchIndex(content)
	if idx == nil {
		return nil, fmt.Errorf("could not find section %q", sectionName)
	}
	result := slices.Clone(content[:idx[2]])
	result = append(result, replacement...)
	result = append(result, content[idx[3]:]...)
	return result, nil
}

type onOff bool

func (o onOff) String() string {
	if o {
		return "on"
	} else {
		return "off"
	}
}
