// 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
	Feature string // everything about the feature other than the package
	Issue   int    // the issue that introduced the feature, or 0 if none
}

var apiFileLineRegexp = regexp.MustCompile(`^pkg ([^,]+), ([^#]*)(#\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 WORDS #ISSUE
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 == "" {
			continue
		}
		matches := apiFileLineRegexp.FindStringSubmatch(line)
		if len(matches) == 0 {
			return nil, fmt.Errorf("%s: malformed line %q", filename, line)
		}
		f := APIFeature{
			Package: matches[1],
			Feature: strings.TrimSpace(matches[2]),
		}
		if len(matches) > 3 && len(matches[3]) > 0 {
			var err error
			f.Issue, err = strconv.Atoi(matches[3][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))
}
