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

package relnote

import (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"

	"golang.org/x/mod/module"
	md "rsc.io/markdown"
)

// addSymbolLinks looks for text like [Buffer] and
// [math.Max] and replaces them with links to standard library
// symbols and packages.
// It uses the given default package for links without a package.
func addSymbolLinks(doc *md.Document, defaultPackage string) {
	addSymbolLinksBlocks(doc.Blocks, defaultPackage)
}

func addSymbolLinksBlocks(bs []md.Block, defaultPackage string) {
	for _, b := range bs {
		addSymbolLinksBlock(b, defaultPackage)
	}
}

func addSymbolLinksBlock(b md.Block, defaultPackage string) {
	switch b := b.(type) {
	case *md.Heading:
		addSymbolLinksBlock(b.Text, defaultPackage)
	case *md.Text:
		b.Inline = addSymbolLinksInlines(b.Inline, defaultPackage)
	case *md.List:
		addSymbolLinksBlocks(b.Items, defaultPackage)
	case *md.Item:
		addSymbolLinksBlocks(b.Blocks, defaultPackage)
	case *md.Paragraph:
		addSymbolLinksBlock(b.Text, defaultPackage)
	case *md.Quote:
		addSymbolLinksBlocks(b.Blocks, defaultPackage)
	// no links in these blocks
	case *md.CodeBlock:
	case *md.HTMLBlock:
	case *md.Empty:
	case *md.ThematicBreak:
	default:
		panic(fmt.Sprintf("unknown block type %T", b))
	}
}

// addSymbolLinksInlines looks for symbol links in the slice of inline markdown
// elements. It returns a new slice of inline elements with links added.
func addSymbolLinksInlines(ins []md.Inline, defaultPackage string) []md.Inline {
	ins = splitAtBrackets(ins)
	var res []md.Inline
	for i := 0; i < len(ins); i++ {
		if txt := symbolLinkText(i, ins); txt != "" {
			link, ok := symbolLink(txt, defaultPackage)
			if ok {
				res = append(res, link)
				i += 2
				continue
			}
		}

		switch in := ins[i].(type) {
		case *md.Strong:
			res = append(res, addSymbolLinksInlines(in.Inner, defaultPackage)...)
		case *md.Emph:
			res = append(res, addSymbolLinksInlines(in.Inner, defaultPackage)...)
		case *md.Del:
			res = append(res, addSymbolLinksInlines(in.Inner, defaultPackage)...)
		// Don't look for links in anything else.
		default:
			res = append(res, in)
		}
	}
	return res
}

// splitAtBrackets rewrites ins so that every '[' and ']' is the only character
// of its Plain.
// For example, the element
//
//	[Plain("the [Buffer] is")]
//
// is rewritten to
//
//	[Plain("the "), Plain("["), Plain("Buffer"), Plain("]"), Plain(" is")]
//
// This transformation simplifies looking for symbol links.
func splitAtBrackets(ins []md.Inline) []md.Inline {
	var res []md.Inline
	for _, in := range ins {
		if p, ok := in.(*md.Plain); ok {
			text := p.Text
			for len(text) > 0 {
				i := strings.IndexAny(text, "[]")
				// If there are no brackets, the remaining text is a single
				// Plain and we are done.
				if i < 0 {
					res = append(res, &md.Plain{Text: text})
					break
				}
				// There is a bracket; make Plains for it and the text before it (if any).
				if i > 0 {
					res = append(res, &md.Plain{Text: text[:i]})
				}
				res = append(res, &md.Plain{Text: text[i : i+1]})
				text = text[i+1:]
			}
		} else {
			res = append(res, in)
		}
	}
	return res
}

// symbolLinkText returns the text of a possible symbol link.
// It is given a slice of Inline elements and an index into the slice.
// If the index refers to a sequence of elements
//
//	[Plain("["), Plain_or_Code(text), Plain("]")]
//
// and the brackets are adjacent to the right kind of runes for a link, then
// symbolLinkText returns the text of the middle element.
// Otherwise it returns the empty string.
func symbolLinkText(i int, ins []md.Inline) string {
	// plainText returns the text of ins[j] if it is a Plain element, or "" otherwise.
	plainText := func(j int) string {
		if j < 0 || j >= len(ins) {
			return ""
		}
		if p, ok := ins[j].(*md.Plain); ok {
			return p.Text
		}
		return ""
	}

	// ins[i] must be a "[".
	if plainText(i) != "[" {
		return ""
	}
	// The open bracket must be preceeded by a link-adjacent rune (or by nothing).
	if t := plainText(i - 1); t != "" {
		r, _ := utf8.DecodeLastRuneInString(t)
		if !isLinkAdjacentRune(r) {
			return ""
		}
	}
	// The element after the next must be a ']'.
	if plainText(i+2) != "]" {
		return ""
	}
	// The ']' must be followed by a link-adjacent rune (or by nothing).
	if t := plainText(i + 3); t != "" {
		r, _ := utf8.DecodeRuneInString(t)
		if !isLinkAdjacentRune(r) {
			return ""
		}
	}

	// ins[i+1] must be a Plain or a Code.
	// Its text is the symbol to link to.
	if i+1 >= len(ins) {
		return ""
	}
	switch in := ins[i+1].(type) {
	case *md.Plain:
		return in.Text
	case *md.Code:
		return in.Text
	default:
		return ""
	}
}

// symbolLink converts s into a Link and returns it and true, or nil and false if
// s is not a valid link or is surrounded by runes that disqualify it from being
// converted to a link.
//
// The argument s is the text between '[' and ']'.
func symbolLink(s, defaultPackage string) (md.Inline, bool) {
	pkg, sym, ok := splitRef(s)
	if !ok {
		return nil, false
	}
	if pkg == "" {
		if defaultPackage == "" {
			return nil, false
		}
		pkg = defaultPackage
	}
	if sym != "" {
		sym = "#" + sym
	}
	return &md.Link{
		Inner: []md.Inline{&md.Code{Text: s}},
		URL:   fmt.Sprintf("/pkg/%s%s", pkg, sym),
	}, true
}

// isLinkAdjacentRune reports whether r can be adjacent to a symbol link.
// The logic is the same as the go/doc/comment package.
func isLinkAdjacentRune(r rune) bool {
	return unicode.IsPunct(r) || r == ' ' || r == '\t' || r == '\n'
}

// splitRef splits s into a package and possibly a symbol.
// Examples:
//
//	splitRef("math.Max") => ("math", "Max", true)
//	splitRef("bytes.Buffer.String") => ("bytes", "Buffer.String", true)
//	splitRef("math") => ("math", "", true)
func splitRef(s string) (pkg, name string, ok bool) {
	s = strings.TrimPrefix(s, "*")
	pkg, name, ok = splitDocName(s)
	var recv string
	if ok {
		pkg, recv, _ = splitDocName(pkg)
	}
	if pkg != "" {
		if err := module.CheckImportPath(pkg); err != nil {
			return "", "", false
		}
	}
	if recv != "" {
		name = recv + "." + name
	}
	return pkg, name, true
}

// The following functions were copied from go/doc/comment/parse.go.

// If text is of the form before.Name, where Name is a capitalized Go identifier,
// then splitDocName returns before, name, true.
// Otherwise it returns text, "", false.
func splitDocName(text string) (before, name string, foundDot bool) {
	i := strings.LastIndex(text, ".")
	name = text[i+1:]
	if !isName(name) {
		return text, "", false
	}
	if i >= 0 {
		before = text[:i]
	}
	return before, name, true
}

// isName reports whether s is a capitalized Go identifier (like Name).
func isName(s string) bool {
	t, ok := ident(s)
	if !ok || t != s {
		return false
	}
	r, _ := utf8.DecodeRuneInString(s)
	return unicode.IsUpper(r)
}

// ident checks whether s begins with a Go identifier.
// If so, it returns the identifier, which is a prefix of s, and ok == true.
// Otherwise it returns "", false.
// The caller should skip over the first len(id) bytes of s
// before further processing.
func ident(s string) (id string, ok bool) {
	// Scan [\pL_][\pL_0-9]*
	n := 0
	for n < len(s) {
		if c := s[n]; c < utf8.RuneSelf {
			if isIdentASCII(c) && (n > 0 || c < '0' || c > '9') {
				n++
				continue
			}
			break
		}
		r, nr := utf8.DecodeRuneInString(s[n:])
		if unicode.IsLetter(r) {
			n += nr
			continue
		}
		break
	}
	return s[:n], n > 0
}

// isIdentASCII reports whether c is an ASCII identifier byte.
func isIdentASCII(c byte) bool {
	// mask is a 128-bit bitmap with 1s for allowed bytes,
	// so that the byte c can be tested with a shift and an and.
	// If c > 128, then 1<<c and 1<<(c-64) will both be zero,
	// and this function will return false.
	const mask = 0 |
		(1<<26-1)<<'A' |
		(1<<26-1)<<'a' |
		(1<<10-1)<<'0' |
		1<<'_'

	return ((uint64(1)<<c)&(mask&(1<<64-1)) |
		(uint64(1)<<(c-64))&(mask>>64)) != 0
}
