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

// This file implements LinkifyText which introduces
// links for identifiers pointing to their declarations.
// The approach does not cover all cases because godoc
// doesn't have complete type information, but it's
// reasonably good for browsing.

package godoc

import (
	"fmt"
	"go/ast"
	"go/token"
	"io"
	"strconv"
)

// LinkifyText HTML-escapes source text and writes it to w.
// Identifiers that are in a "use" position (i.e., that are
// not being declared), are wrapped with HTML links pointing
// to the respective declaration, if possible. Comments are
// formatted the same way as with FormatText.
//
func LinkifyText(w io.Writer, text []byte, n ast.Node) {
	links := linksFor(n)

	i := 0     // links index
	prev := "" // prev HTML tag
	linkWriter := func(w io.Writer, _ int, start bool) {
		// end tag
		if !start {
			if prev != "" {
				fmt.Fprintf(w, `</%s>`, prev)
				prev = ""
			}
			return
		}

		// start tag
		prev = ""
		if i < len(links) {
			switch info := links[i]; {
			case info.path != "" && info.name == "":
				// package path
				fmt.Fprintf(w, `<a href="/pkg/%s/">`, info.path)
				prev = "a"
			case info.path != "" && info.name != "":
				// qualified identifier
				fmt.Fprintf(w, `<a href="/pkg/%s/#%s">`, info.path, info.name)
				prev = "a"
			case info.path == "" && info.name != "":
				// local identifier
				if info.mode == identVal {
					fmt.Fprintf(w, `<span id="%s">`, info.name)
					prev = "span"
				} else if ast.IsExported(info.name) {
					fmt.Fprintf(w, `<a href="#%s">`, info.name)
					prev = "a"
				}
			}
			i++
		}
	}

	idents := tokenSelection(text, token.IDENT)
	comments := tokenSelection(text, token.COMMENT)
	FormatSelections(w, text, linkWriter, idents, selectionTag, comments)
}

// A link describes the (HTML) link information for an identifier.
// The zero value of a link represents "no link".
//
type link struct {
	mode       identMode
	path, name string // package path, identifier name
}

// The identMode describes how an identifier is "used" at its source location.
type identMode int

const (
	identUse identMode = iota // identifier is used (must be zero value for identMode)
	identDef                  // identifier is defined
	identVal                  // identifier is defined in a const or var declaration
)

// linksFor returns the list of links for the identifiers used
// by node in the same order as they appear in the source.
//
func linksFor(node ast.Node) (links []link) {
	// linkMap tracks link information for each ast.Ident node. Entries may
	// be created out of source order (for example, when we visit a parent
	// definition node). These links are appended to the returned slice when
	// their ast.Ident nodes are visited.
	linkMap := make(map[*ast.Ident]link)

	ast.Inspect(node, func(node ast.Node) bool {
		switch n := node.(type) {
		case *ast.Field:
			for _, n := range n.Names {
				linkMap[n] = link{mode: identDef}
			}
		case *ast.ImportSpec:
			if name := n.Name; name != nil {
				linkMap[name] = link{mode: identDef}
			}
		case *ast.ValueSpec:
			for _, n := range n.Names {
				linkMap[n] = link{mode: identVal, name: n.Name}
			}
		case *ast.TypeSpec:
			linkMap[n.Name] = link{mode: identDef}
		case *ast.AssignStmt:
			// Short variable declarations only show up if we apply
			// this code to all source code (as opposed to exported
			// declarations only).
			if n.Tok == token.DEFINE {
				// Some of the lhs variables may be re-declared,
				// so technically they are not defs. We don't
				// care for now.
				for _, x := range n.Lhs {
					// Each lhs expression should be an
					// ident, but we are conservative and check.
					if n, _ := x.(*ast.Ident); n != nil {
						linkMap[n] = link{mode: identVal}
					}
				}
			}
		case *ast.SelectorExpr:
			// Detect qualified identifiers of the form pkg.ident.
			// If anything fails we return true and collect individual
			// identifiers instead.
			if x, _ := n.X.(*ast.Ident); x != nil {
				// Create links only if x is a qualified identifier.
				if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
					if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
						// spec.Path.Value is the import path
						if path, err := strconv.Unquote(spec.Path.Value); err == nil {
							// Register two links, one for the package
							// and one for the qualified identifier.
							linkMap[x] = link{mode: identUse, path: path}
							linkMap[n.Sel] = link{mode: identUse, path: path, name: n.Sel.Name}
						}
					}
				}
			}
		case *ast.CompositeLit:
			// Detect field names within composite literals. These links should
			// be prefixed by the type name.
			fieldPath := ""
			prefix := ""
			switch typ := n.Type.(type) {
			case *ast.Ident:
				prefix = typ.Name + "."
			case *ast.SelectorExpr:
				if x, _ := typ.X.(*ast.Ident); x != nil {
					// Create links only if x is a qualified identifier.
					if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
						if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
							// spec.Path.Value is the import path
							if path, err := strconv.Unquote(spec.Path.Value); err == nil {
								// Register two links, one for the package
								// and one for the qualified identifier.
								linkMap[x] = link{mode: identUse, path: path}
								linkMap[typ.Sel] = link{mode: identUse, path: path, name: typ.Sel.Name}
								fieldPath = path
								prefix = typ.Sel.Name + "."
							}
						}
					}
				}
			}
			for _, e := range n.Elts {
				if kv, ok := e.(*ast.KeyValueExpr); ok {
					if k, ok := kv.Key.(*ast.Ident); ok {
						// Note: there is some syntactic ambiguity here. We cannot determine
						// if this is a struct literal or a map literal without type
						// information. We assume struct literal.
						name := prefix + k.Name
						linkMap[k] = link{mode: identUse, path: fieldPath, name: name}
					}
				}
			}
		case *ast.Ident:
			if l, ok := linkMap[n]; ok {
				links = append(links, l)
			} else {
				l := link{mode: identUse, name: n.Name}
				if n.Obj == nil && predeclared[n.Name] {
					l.path = builtinPkgPath
				}
				links = append(links, l)
			}
		}
		return true
	})
	return
}

// The predeclared map represents the set of all predeclared identifiers.
// TODO(gri) This information is also encoded in similar maps in go/doc,
//           but not exported. Consider exporting an accessor and using
//           it instead.
var predeclared = map[string]bool{
	"bool":       true,
	"byte":       true,
	"complex64":  true,
	"complex128": true,
	"error":      true,
	"float32":    true,
	"float64":    true,
	"int":        true,
	"int8":       true,
	"int16":      true,
	"int32":      true,
	"int64":      true,
	"rune":       true,
	"string":     true,
	"uint":       true,
	"uint8":      true,
	"uint16":     true,
	"uint32":     true,
	"uint64":     true,
	"uintptr":    true,
	"true":       true,
	"false":      true,
	"iota":       true,
	"nil":        true,
	"append":     true,
	"cap":        true,
	"close":      true,
	"complex":    true,
	"copy":       true,
	"delete":     true,
	"imag":       true,
	"len":        true,
	"make":       true,
	"new":        true,
	"panic":      true,
	"print":      true,
	"println":    true,
	"real":       true,
	"recover":    true,
}
