// Copyright 2023 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 relnote supports working with release notes.
//
// Its main feature is the ability to merge Markdown fragments into a single
// document. (See [Merge].)
//
// This package has minimal imports, so that it can be vendored into the
// main go repo.
package relnote

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/fs"
	"path"
	"regexp"
	"slices"
	"strconv"
	"strings"

	md "rsc.io/markdown"
)

// NewParser returns a properly configured Markdown parser.
func NewParser() *md.Parser {
	var p md.Parser
	p.HeadingIDs = true
	return &p
}

// CheckFragment reports problems in a release-note fragment.
func CheckFragment(data string) error {
	doc := NewParser().Parse(data)
	// Check that the content of the document contains either a TODO or at least one sentence.
	txt := ""
	if len(doc.Blocks) > 0 {
		txt = text(doc)
	}
	if !strings.Contains(txt, "TODO") && !strings.ContainsAny(txt, ".?!") {
		return errors.New("File must contain a complete sentence or a TODO.")
	}
	return nil
}

// text returns all the text in a block, without any formatting.
func text(b md.Block) string {
	switch b := b.(type) {
	case *md.Document:
		return blocksText(b.Blocks)
	case *md.Heading:
		return text(b.Text)
	case *md.Text:
		return inlineText(b.Inline)
	case *md.CodeBlock:
		return strings.Join(b.Text, "\n")
	case *md.HTMLBlock:
		return strings.Join(b.Text, "\n")
	case *md.List:
		return blocksText(b.Items)
	case *md.Item:
		return blocksText(b.Blocks)
	case *md.Empty:
		return ""
	case *md.Paragraph:
		return text(b.Text)
	case *md.Quote:
		return blocksText(b.Blocks)
	case *md.ThematicBreak:
		return "---"
	default:
		panic(fmt.Sprintf("unknown block type %T", b))
	}
}

// blocksText returns all the text in a slice of block nodes.
func blocksText(bs []md.Block) string {
	var d strings.Builder
	for _, b := range bs {
		io.WriteString(&d, text(b))
		fmt.Fprintln(&d)
	}
	return d.String()
}

// inlineText returns all the next in a slice of inline nodes.
func inlineText(ins []md.Inline) string {
	var buf bytes.Buffer
	for _, in := range ins {
		in.PrintText(&buf)
	}
	return buf.String()
}

// Merge combines the markdown documents (files ending in ".md") in the tree rooted
// at fs into a single document.
// The blocks of the documents are concatenated in lexicographic order by filename.
// Heading with no content are removed.
// The link keys must be unique, and are combined into a single map.
//
// Files in the "minor changes" directory (the unique directory matching the glob
// "*stdlib/*minor") are named after the package to which they refer, and will have
// the package heading inserted automatically and links to other standard library
// symbols expanded automatically. For example, if a file *stdlib/minor/bytes/f.md
// contains the text
//
//	[Reader] implements [io.Reader].
//
// then that will become
//
//	[Reader](/pkg/bytes#Reader) implements [io.Reader](/pkg/io#Reader).
func Merge(fsys fs.FS) (*md.Document, error) {
	filenames, err := sortedMarkdownFilenames(fsys)
	if err != nil {
		return nil, err
	}
	doc := &md.Document{Links: map[string]*md.Link{}}
	var prevPkg string // previous stdlib package, if any
	for _, filename := range filenames {
		newdoc, err := parseMarkdownFile(fsys, filename)
		if err != nil {
			return nil, err
		}
		if len(newdoc.Blocks) == 0 {
			continue
		}
		pkg := stdlibPackage(filename)
		// Autolink Go symbols.
		addSymbolLinks(newdoc, pkg)
		if len(doc.Blocks) > 0 {
			// If this is the first file of a new stdlib package under the "Minor changes
			// to the library" section, insert a heading for the package.
			if pkg != "" && pkg != prevPkg {
				h := stdlibPackageHeading(pkg, lastBlock(doc).Pos().EndLine)
				doc.Blocks = append(doc.Blocks, h)
			}
			prevPkg = pkg
			// Put a blank line between the current and new blocks, so that the end
			// of a file acts as a blank line.
			lastLine := lastBlock(doc).Pos().EndLine
			delta := lastLine + 2 - newdoc.Blocks[0].Pos().StartLine
			for _, b := range newdoc.Blocks {
				addLines(b, delta)
			}
		}
		// Append non-empty blocks to the result document.
		for _, b := range newdoc.Blocks {
			if _, ok := b.(*md.Empty); !ok {
				doc.Blocks = append(doc.Blocks, b)
			}
		}
		// Merge link references.
		for key, link := range newdoc.Links {
			if doc.Links[key] != nil {
				return nil, fmt.Errorf("duplicate link reference %q; second in %s", key, filename)
			}
			doc.Links[key] = link
		}
	}
	// Remove headings with empty contents.
	doc.Blocks = removeEmptySections(doc.Blocks)
	if len(doc.Blocks) > 0 && len(doc.Links) > 0 {
		// Add a blank line to separate the links.
		lastPos := lastBlock(doc).Pos()
		lastPos.StartLine += 2
		lastPos.EndLine += 2
		doc.Blocks = append(doc.Blocks, &md.Empty{Position: lastPos})
	}
	return doc, nil
}

// stdlibPackage returns the standard library package for the given filename.
// If the filename does not represent a package, it returns the empty string.
// A filename represents package P if it is in a directory matching the glob
// "*stdlib/*minor/P".
func stdlibPackage(filename string) string {
	dir, rest, _ := strings.Cut(filename, "/")
	if !strings.HasSuffix(dir, "stdlib") {
		return ""
	}
	dir, rest, _ = strings.Cut(rest, "/")
	if !strings.HasSuffix(dir, "minor") {
		return ""
	}
	pkg := path.Dir(rest)
	if pkg == "." {
		return ""
	}
	return pkg
}

func stdlibPackageHeading(pkg string, lastLine int) *md.Heading {
	line := lastLine + 2
	pos := md.Position{StartLine: line, EndLine: line}
	return &md.Heading{
		Position: pos,
		Level:    4,
		Text: &md.Text{
			Position: pos,
			Inline: []md.Inline{
				&md.Link{
					Inner: []md.Inline{&md.Plain{Text: pkg}},
					URL:   "/pkg/" + pkg + "/",
				},
			},
		},
	}
}

// removeEmptySections removes headings with no content. A heading has no content
// if there are no blocks between it and the next heading at the same level, or the
// end of the document.
func removeEmptySections(bs []md.Block) []md.Block {
	res := bs[:0]
	delta := 0 // number of lines by which to adjust positions

	// Remove preceding headings at same or higher level; they are empty.
	rem := func(level int) {
		for len(res) > 0 {
			last := res[len(res)-1]
			if lh, ok := last.(*md.Heading); ok && lh.Level >= level {
				res = res[:len(res)-1]
				// Adjust subsequent block positions by the size of this block
				// plus 1 for the blank line between headings.
				delta += lh.EndLine - lh.StartLine + 2
			} else {
				break
			}
		}
	}

	for _, b := range bs {
		if h, ok := b.(*md.Heading); ok {
			rem(h.Level)
		}
		addLines(b, -delta)
		res = append(res, b)
	}
	// Remove empty headings at the end of the document.
	rem(1)
	return res
}

func sortedMarkdownFilenames(fsys fs.FS) ([]string, error) {
	var filenames []string
	err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if !d.IsDir() && strings.HasSuffix(path, ".md") {
			filenames = append(filenames, path)
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	// '.' comes before '/', which comes before alphanumeric characters.
	// So just sorting the list will put a filename like "net.md" before
	// the directory "net". That is what we want.
	slices.Sort(filenames)
	return filenames, nil
}

// lastBlock returns the last block in the document.
// It panics if the document has no blocks.
func lastBlock(doc *md.Document) md.Block {
	return doc.Blocks[len(doc.Blocks)-1]
}

// addLines adds n lines to the position of b.
// n can be negative.
func addLines(b md.Block, n int) {
	pos := position(b)
	pos.StartLine += n
	pos.EndLine += n
}

func position(b md.Block) *md.Position {
	switch b := b.(type) {
	case *md.Heading:
		return &b.Position
	case *md.Text:
		return &b.Position
	case *md.CodeBlock:
		return &b.Position
	case *md.HTMLBlock:
		return &b.Position
	case *md.List:
		return &b.Position
	case *md.Item:
		return &b.Position
	case *md.Empty:
		return &b.Position
	case *md.Paragraph:
		return &b.Position
	case *md.Quote:
		return &b.Position
	case *md.ThematicBreak:
		return &b.Position
	default:
		panic(fmt.Sprintf("unknown block type %T", b))
	}
}

func parseMarkdownFile(fsys fs.FS, path string) (*md.Document, error) {
	f, err := fsys.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	data, err := io.ReadAll(f)
	if err != nil {
		return nil, err
	}
	in := string(data)
	doc := NewParser().Parse(in)
	return doc, nil
}

// An APIFeature is a symbol mentioned in an API file,
// like the ones in the main go repo in the api directory.
type APIFeature struct {
	Package string // package that the feature is in
	Build   string // build that the symbol is relevant for (e.g. GOOS, GOARCH)
	Feature string // everything about the feature other than the package
	Issue   int    // the issue that introduced the feature, or 0 if none
}

// This regexp has four capturing groups: package, build, feature and issue.
var apiFileLineRegexp = regexp.MustCompile(`^pkg ([^ \t]+)[ \t]*(\([^)]+\))?, ([^#]*)(#\d+)?$`)

// parseAPIFile parses a file in the api format and returns a list of the file's features.
// A feature is represented by a single line that looks like
//
//	pkg PKG (BUILD) FEATURE #ISSUE
//
// where the BUILD and ISSUE may be absent.
func parseAPIFile(fsys fs.FS, filename string) ([]APIFeature, error) {
	f, err := fsys.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	var features []APIFeature
	scan := bufio.NewScanner(f)
	for scan.Scan() {
		line := strings.TrimSpace(scan.Text())
		if line == "" || line[0] == '#' {
			continue
		}
		matches := apiFileLineRegexp.FindStringSubmatch(line)
		if len(matches) == 0 {
			return nil, fmt.Errorf("%s: malformed line %q", filename, line)
		}
		if len(matches) != 5 {
			return nil, fmt.Errorf("wrong number of matches for line %q", line)
		}
		f := APIFeature{
			Package: matches[1],
			Build:   matches[2],
			Feature: strings.TrimSpace(matches[3]),
		}
		if issue := matches[4]; issue != "" {
			var err error
			f.Issue, err = strconv.Atoi(issue[1:]) // skip leading '#'
			if err != nil {
				return nil, err
			}
		}
		features = append(features, f)
	}
	if scan.Err() != nil {
		return nil, scan.Err()
	}
	return features, nil
}

// GroupAPIFeaturesByFile returns a map of the given features keyed by
// the doc filename that they are associated with.
// A feature with package P and issue N should be documented in the file
// "P/N.md".
func GroupAPIFeaturesByFile(fs []APIFeature) (map[string][]APIFeature, error) {
	m := map[string][]APIFeature{}
	for _, f := range fs {
		if f.Issue == 0 {
			return nil, fmt.Errorf("%+v: zero issue", f)
		}
		filename := fmt.Sprintf("%s/%d.md", f.Package, f.Issue)
		m[filename] = append(m[filename], f)
	}
	return m, nil
}

// CheckAPIFile reads the api file at filename in apiFS, and checks the corresponding
// release-note files under docFS. It checks that the files exist and that they have
// some minimal content (see [CheckFragment]).
// The docRoot argument is the path from the repo or project root to the root of docFS.
// It is used only for error messages.
func CheckAPIFile(apiFS fs.FS, filename string, docFS fs.FS, docRoot string) error {
	features, err := parseAPIFile(apiFS, filename)
	if err != nil {
		return err
	}
	byFile, err := GroupAPIFeaturesByFile(features)
	if err != nil {
		return err
	}
	var filenames []string
	for fn := range byFile {
		filenames = append(filenames, fn)
	}
	slices.Sort(filenames)
	mcDir, err := minorChangesDir(docFS)
	if err != nil {
		return err
	}
	var errs []error
	for _, fn := range filenames {
		// Use path.Join for consistency with io/fs pathnames.
		fn = path.Join(mcDir, fn)
		// TODO(jba): check that the file mentions each feature?
		if err := checkFragmentFile(docFS, fn); err != nil {
			errs = append(errs, fmt.Errorf("%s: %v\nSee doc/README.md for more information.", path.Join(docRoot, fn), err))
		}
	}
	return errors.Join(errs...)
}

// minorChangesDir returns the unique directory in docFS that corresponds to the
// "Minor changes to the standard library" section of the release notes.
func minorChangesDir(docFS fs.FS) (string, error) {
	dirs, err := fs.Glob(docFS, "*stdlib/*minor")
	if err != nil {
		return "", err
	}
	var bad string
	if len(dirs) == 0 {
		bad = "No"
	} else if len(dirs) > 1 {
		bad = "More than one"
	}
	if bad != "" {
		return "", fmt.Errorf("%s directory matches *stdlib/*minor.\nThis shouldn't happen; please file a bug at https://go.dev/issues/new.",
			bad)
	}
	return dirs[0], nil
}

func checkFragmentFile(fsys fs.FS, filename string) error {
	f, err := fsys.Open(filename)
	if err != nil {
		if errors.Is(err, fs.ErrNotExist) {
			err = errors.New("File does not exist. Every API change must have a corresponding release note file.")
		}
		return err
	}
	defer f.Close()
	data, err := io.ReadAll(f)
	return CheckFragment(string(data))
}
