// Copyright 2022 The Fuchsia 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 docgen

import (
	"fmt"
	"go.fuchsia.dev/fuchsia/tools/cppdocgen/clangdoc"
	"log"
	"path"
	"sort"
)

type IndexSettings struct {
	// Path to the build directory where the clang-doc paths are relative to.
	BuildDir string

	// Names of the header files we want to index.
	Headers map[string]struct{}
}

func MakeIndexSettings(buildDir string) IndexSettings {
	return IndexSettings{
		BuildDir: buildDir,
		Headers:  make(map[string]struct{}),
	}
}

func (s IndexSettings) ShouldIndexInHeader(hdrName string) bool {
	_, found := s.Headers[hdrName]
	return found
}

// HeaderPath returns the path for the given build-dir-relative (what clang-doc generates) header
// path.
func (s IndexSettings) HeaderPath(h string) string {
	return path.Join(s.BuildDir, h)
}

// Flattened version of everything stored in this library.
type Index struct {
	// All nonmember functions/records in all non-anonymous namespaces, indexed by the USR/Name.
	// Since functions overloads may have name collisions, FunctionNames may not include
	// everything (it currently stores the last one of that name encountered). FunctionUsrs
	// will include everything since Clang will generate a unique USR for each function.
	//
	// This could be enhanced in the future if needed to map a name to a list of functions. But
	// currently we only use the name index to generate links where there can only be one
	// destination anyway.
	FunctionUsrs  map[string]*clangdoc.FunctionInfo
	FunctionNames map[string]*clangdoc.FunctionInfo

	// Toplevel records (classes, structs, and unions), indexed by the Name/USR.
	RecordNames map[string]*clangdoc.RecordInfo
	RecordUsrs  map[string]*clangdoc.RecordInfo

	// All unique header files in this library indexed by their file name.
	Headers map[string]*Header

	// All unique preprocessor defines in this library indexed by their name.
	Defines map[string]*Define

	// All toplevel and namespaced enums indexed by their name.
	Enums map[string]*clangdoc.EnumInfo

	// All typedefs indexed by their name.
	Typedefs map[string]*clangdoc.TypedefInfo
}

// Returns a sorted list of all functions.
func (index Index) AllFunctions() []*clangdoc.FunctionInfo {
	result := make([]*clangdoc.FunctionInfo, 0, len(index.FunctionUsrs))
	for _, fn := range index.FunctionUsrs {
		result = append(result, fn)
	}
	sort.Sort(functionByName(result))
	return result
}

// Returns a sorted list of all records.
func (index Index) AllRecords() []*clangdoc.RecordInfo {
	result := make([]*clangdoc.RecordInfo, 0, len(index.RecordUsrs))
	for _, r := range index.RecordUsrs {
		result = append(result, r)
	}
	sort.Sort(recordByName(result))
	return result
}

// AllDefines returns a sorted list of all defines.
func (index Index) AllDefines() []*Define {
	result := make([]*Define, 0, len(index.Defines))
	for _, d := range index.Defines {
		result = append(result, d)
	}
	sort.Sort(defineByName(result))
	return result
}

func (index *Index) HeaderForFileName(file string) *Header {
	header := index.Headers[file]
	if header == nil {
		// New item, init Header struct.
		header = &Header{Name: file}
		index.Headers[file] = header
	}
	return header
}

type FunctionGroup struct {
	// Nonempty when an explicit title is given. Empty means just use the first name.
	ExplicitTitle string

	Funcs []*clangdoc.FunctionInfo
}

// Interface for sorting a function group by the first function's name.
type functionGroupByTitle []*FunctionGroup

func (f functionGroupByTitle) Len() int {
	return len(f)
}
func (f functionGroupByTitle) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}
func (f functionGroupByTitle) Less(i, j int) bool {
	getName := func(g *FunctionGroup) string {
		if len(g.ExplicitTitle) > 0 {
			return g.ExplicitTitle
		}
		return g.Funcs[0].Name
	}
	return getName(f[i]) < getName(f[j])
}

// Interface for sorting an enum list by name.
type enumByName []*clangdoc.EnumInfo

func (f enumByName) Len() int {
	return len(f)
}
func (f enumByName) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}
func (f enumByName) Less(i, j int) bool {
	return f[i].Name < f[j].Name
}

// Interface for sorting a typedef list by name.
type typedefByName []*clangdoc.TypedefInfo

func (f typedefByName) Len() int {
	return len(f)
}
func (f typedefByName) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}
func (f typedefByName) Less(i, j int) bool {
	return f[i].Name < f[j].Name
}

type DefineGroup struct {
	// Nonempty when an explicit title is given. Empty means just use the first name.
	ExplicitTitle string

	Defines []*Define
}

// Interface for sorting a define group by the first define's name.
type defineGroupByTitle []*DefineGroup

func (f defineGroupByTitle) Len() int {
	return len(f)
}
func (f defineGroupByTitle) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}
func (f defineGroupByTitle) Less(i, j int) bool {
	getName := func(g *DefineGroup) string {
		if len(g.ExplicitTitle) > 0 {
			return g.ExplicitTitle
		}
		return g.Defines[0].Name
	}
	return getName(f[i]) < getName(f[j])
}

func indexFunction(settings IndexSettings, index *Index, f *clangdoc.FunctionInfo) {
	// When the function has no separate declaration location, use the definition location.
	var loc = f.GetLocation()
	if len(loc.Filename) == 0 {
		fmt.Printf("WARNING: Function %s does not have a location.\n", f.Name)
	} else if settings.ShouldIndexInHeader(loc.Filename) &&
		!commentContains(f.Description, NoDocTag) {
		// TODO(brettw) there can be multiple locations! I think this might be for every
		// forward declaration. In this case we will want to pick the "best" one.
		index.FunctionUsrs[f.USR] = f
		index.FunctionNames[functionFullName(f)] = f

		decl := loc.Filename

		header := index.HeaderForFileName(decl)
		header.Functions = append(header.Functions, f)
		index.Headers[decl] = header
	}
}

func indexRecord(settings IndexSettings, index *Index, r *clangdoc.RecordInfo) {
	if settings.ShouldIndexInHeader(r.DefLocation.Filename) &&
		!commentContains(r.Description, NoDocTag) {
		index.RecordUsrs[r.USR] = r
		index.RecordNames[recordFullName(r)] = r

		header := index.HeaderForFileName(r.DefLocation.Filename)
		header.Records = append(header.Records, r)
	}
}

func indexEnum(settings IndexSettings, index *Index, e *clangdoc.EnumInfo) {
	if settings.ShouldIndexInHeader(e.DefLocation.Filename) &&
		!commentContains(e.Description, NoDocTag) {
		index.Enums[enumFullName(e)] = e

		header := index.HeaderForFileName(e.DefLocation.Filename)
		header.Enums = append(header.Enums, e)
	}
}

func indexTypedef(settings IndexSettings, index *Index, t *clangdoc.TypedefInfo) {
	if settings.ShouldIndexInHeader(t.DefLocation.Filename) &&
		!commentContains(t.Description, NoDocTag) {
		index.Typedefs[typedefFullName(t)] = t

		header := index.HeaderForFileName(t.DefLocation.Filename)
		header.Typedefs = append(header.Typedefs, t)
	}
}

func indexNamespace(settings IndexSettings, index *Index, r *clangdoc.NamespaceInfo) {
	for _, f := range r.ChildFunctions {
		indexFunction(settings, index, f)
	}
	for _, c := range r.ChildNamespaces {
		indexNamespace(settings, index, c)
	}
	for _, r := range r.ChildRecords {
		indexRecord(settings, index, r)
	}
	for _, e := range r.ChildEnums {
		indexEnum(settings, index, e)
	}
	for _, t := range r.ChildTypedefs {
		indexTypedef(settings, index, t)
	}
}

// Returns true if the two locations have a comment or a blank line separating them.
func (h *Header) hasSeparatorsBetweenLocations(a clangdoc.Location, b clangdoc.Location) bool {
	// Note: line numbers are 1-based.
	if a.LineNumber < 1 || a.LineNumber > len(h.LineClasses) ||
		b.LineNumber < 1 || b.LineNumber > len(h.LineClasses) {
		// Something is out-of-range, assume separated.
		return true
	}
	if a.LineNumber > b.LineNumber {
		log.Fatal("Line numbers not in order")
	}

	for line := a.LineNumber + 1; line < b.LineNumber; line++ {
		// The array is 0-indexed while |line| is 1-indexed.
		if h.LineClasses[line-1] == LineClassBlank || h.LineClasses[line-1] == LineClassComment {
			return true
		}
	}
	return false
}

func (h *Header) groupFunctions(f []*clangdoc.FunctionInfo) []*FunctionGroup {
	if len(f) == 0 {
		return nil
	}

	byLoc := make([]*clangdoc.FunctionInfo, len(f))
	copy(byLoc, f)
	sort.Sort(functionByLocation(byLoc))

	groups := make([]*FunctionGroup, 0, len(f))

	// Makes a new group containing the given function. The group is appended to the list.
	makeNewGroup := func(firstFunc *clangdoc.FunctionInfo) (g *FunctionGroup) {
		g = &FunctionGroup{}
		g.Funcs = make([]*clangdoc.FunctionInfo, 1)
		g.Funcs[0] = firstFunc
		headingLine, _ := extractCommentHeading1(firstFunc.Description)
		g.ExplicitTitle = trimMarkdownHeadings(headingLine)

		groups = append(groups, g)
		return g
	}

	curGroup := makeNewGroup(byLoc[0])

	for i := 1; i < len(byLoc); i++ {
		hasSeparators := h.hasSeparatorsBetweenLocations(
			byLoc[i-1].GetLocation(), byLoc[i].GetLocation())
		nameMatches := curGroup.Funcs[0].Name == f[i].Name

		if !hasSeparators && (nameMatches || len(curGroup.ExplicitTitle) > 0) {
			// Grouped with previous function
			curGroup.Funcs = append(curGroup.Funcs, byLoc[i])
		} else {
			// Not grouped, this function starts a new one.
			curGroup = makeNewGroup(byLoc[i])
		}
	}

	sort.Sort(functionGroupByTitle(groups))
	return groups
}

func (h *Header) groupDefines(allDefines []*Define) []*DefineGroup {
	if len(allDefines) == 0 {
		return nil
	}

	byLoc := make([]*Define, len(allDefines))
	copy(byLoc, allDefines)
	sort.Sort(defineByLocation(byLoc))

	groups := make([]*DefineGroup, 0, len(allDefines))

	// Makes a new group containing the given define. The group is appended to the list.
	makeNewGroup := func(firstDefine *Define) (g *DefineGroup) {
		g = &DefineGroup{}
		g.Defines = make([]*Define, 1)
		g.Defines[0] = firstDefine
		headingLine, _ := extractCommentHeading1(firstDefine.Description)
		g.ExplicitTitle = trimMarkdownHeadings(headingLine)

		groups = append(groups, g)
		return g
	}

	curGroup := makeNewGroup(byLoc[0])

	for i := 1; i < len(byLoc); i++ {
		// Assume if there's no location info there is no separator.
		hasSeparators := h.hasSeparatorsBetweenLocations(byLoc[i-1].Location, byLoc[i].Location)

		// Unlike functions, there is no name matching logic because defines can't have
		// overloaded names.
		if !hasSeparators && len(curGroup.ExplicitTitle) > 0 {
			// Grouped with previous function
			curGroup.Defines = append(curGroup.Defines, byLoc[i])
		} else {
			// Not grouped, this function starts a new one.
			curGroup = makeNewGroup(byLoc[i])
		}
	}

	sort.Sort(defineGroupByTitle(groups))
	return groups
}

func makeEmptyIndex() Index {
	index := Index{}
	index.FunctionUsrs = make(map[string]*clangdoc.FunctionInfo)
	index.FunctionNames = make(map[string]*clangdoc.FunctionInfo)
	index.RecordNames = make(map[string]*clangdoc.RecordInfo)
	index.RecordUsrs = make(map[string]*clangdoc.RecordInfo)
	index.Headers = make(map[string]*Header)
	index.Defines = make(map[string]*Define)
	index.Enums = make(map[string]*clangdoc.EnumInfo)
	index.Typedefs = make(map[string]*clangdoc.TypedefInfo)
	return index
}

func MakeIndex(settings IndexSettings, r *clangdoc.NamespaceInfo) Index {
	index := makeEmptyIndex()
	indexNamespace(settings, &index, r)

	// Get the header comments and #defines for all the headers.
	for name, h := range index.Headers {
		headerValues := ReadHeader(settings.HeaderPath(name))
		h.Description = headerValues.Description
		h.Defines = headerValues.Defines
		h.LineClasses = headerValues.Classes

		// Add the defines to the global index.
		for _, d := range headerValues.Defines {
			index.Defines[d.Name] = d
		}

		// Apply grouping.
		h.FunctionGroups = h.groupFunctions(h.Functions)
		h.DefineGroups = h.groupDefines(h.Defines)
	}

	return index
}
