// Copyright 2021 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 internal

import (
	"fmt"
	"sort"

	"golang.org/x/mod/semver"
	"golang.org/x/pkgsite/internal/derrors"
)

// SymbolSection is the documentation section where a symbol appears.
type SymbolSection string

const (
	SymbolSectionConstants SymbolSection = "Constants"
	SymbolSectionVariables SymbolSection = "Variables"
	SymbolSectionFunctions SymbolSection = "Functions"
	SymbolSectionTypes     SymbolSection = "Types"
)

// SymbolKind is the type of a symbol.
type SymbolKind string

const (
	SymbolKindConstant SymbolKind = "Constant"
	SymbolKindVariable SymbolKind = "Variable"
	SymbolKindFunction SymbolKind = "Function"
	SymbolKindType     SymbolKind = "Type"
	SymbolKindField    SymbolKind = "Field"
	SymbolKindMethod   SymbolKind = "Method"
)

// Symbol is an element in the package API. A symbol can be a constant,
// variable, function, or type.
type Symbol struct {
	SymbolMeta

	// Children contain the child symbols for this symbol. This will
	// only be populated when the SymbolType is "Type". For example, the
	// children of net/http.Handler are FileServer, NotFoundHandler,
	// RedirectHandler, StripPrefix, and TimeoutHandler. Each child
	// symbol will have ParentName set to the Name of this type.
	Children []*SymbolMeta

	// GOOS specifies the execution operating system where the symbol appears.
	GOOS string

	// GOARCH specifies the execution architecture where the symbol appears.
	GOARCH string
}

// SymbolMeta is the metadata for an element in the package API. A symbol can
// be a constant, variable, function, or type.
type SymbolMeta struct {
	// Name is the name of the symbol.
	Name string

	// Synopsis is the one line description of the symbol as displayed
	// in the package documentation.
	Synopsis string

	// Section is the section that a symbol appears in.
	Section SymbolSection

	// Kind is the type of a symbol, which is either a constant, variable,
	// function, type, field or method.
	Kind SymbolKind

	// ParentName if name of the parent type if available, otherwise
	// the empty string. For example, the parent type for
	// net/http.FileServer is Handler.
	ParentName string
}

// SymbolHistory represents the history for when a symbol name was first added
// to a package.
type SymbolHistory struct {
	// m is a map of version to name to SymbolMeta to UnitSymbol.
	// SymbolMeta is stored as a distinct key from name, since it is possible
	// for a symbol in the same version for different build contexts to have
	// different SymbolMeta. For example:
	// https://pkg.go.dev/syscall@go1.16.3#CloseOnExec has function signature:
	// func CloseOnExec(fd int)
	//
	// versus
	// https://pkg.go.dev/syscall?GOOS=windows#CloseOnExec has function
	// signature:
	// func CloseOnExec(fd Handle)
	m map[string]map[string]map[SymbolMeta]*SymbolBuildContexts
}

// NewSymbolHistory returns a new *SymbolHistory.
func NewSymbolHistory() *SymbolHistory {
	return &SymbolHistory{
		m: map[string]map[string]map[SymbolMeta]*SymbolBuildContexts{},
	}
}

// SymbolsAtVersion returns a map of name to SymbolMeta to UnitSymbol for a
// given version.
func (sh *SymbolHistory) SymbolsAtVersion(v string) map[string]map[SymbolMeta]*SymbolBuildContexts {
	return sh.m[v]
}

// Versions returns an array of the versions in versionToNameToUnitSymbol, sorted by
// increasing semver.
func (sh *SymbolHistory) Versions() []string {
	var orderdVersions []string
	for v := range sh.m {
		orderdVersions = append(orderdVersions, v)
	}
	sort.Slice(orderdVersions, func(i, j int) bool {
		return semver.Compare(orderdVersions[i], orderdVersions[j]) == -1
	})
	return orderdVersions
}

// GetSymbol returns the unit symbol for a given name, version and build context.
func (sh *SymbolHistory) GetSymbol(name, v string, build BuildContext) (_ *SymbolMeta, err error) {
	defer derrors.Wrap(&err, "GetSymbol(%q, %q, %v)", name, v, build)
	sav, ok := sh.m[v]
	if !ok {
		return nil, fmt.Errorf("version %q could not be found: %q", v, name)
	}
	stu, ok := sav[name]
	if !ok {
		return nil, fmt.Errorf("symbol %q could not be found at version %q", name, v)
	}
	for sm, us := range stu {
		if us.SupportsBuild(build) {
			return &sm, nil
		}
	}
	return nil, fmt.Errorf("symbol %q does not have build %v at version %q", name, build, v)
}

// AddSymbol adds the given symbol to SymbolHistory.
func (sh *SymbolHistory) AddSymbol(sm SymbolMeta, v string, build BuildContext) {
	sav, ok := sh.m[v]
	if !ok {
		sav = map[string]map[SymbolMeta]*SymbolBuildContexts{}
		sh.m[v] = sav
	}
	stu, ok := sav[sm.Name]
	if !ok {
		stu = map[SymbolMeta]*SymbolBuildContexts{}
		sh.m[v][sm.Name] = stu
	}
	us, ok := stu[sm]
	if !ok {
		us = &SymbolBuildContexts{}
		sh.m[v][sm.Name][sm] = us
	}
	us.AddBuildContext(build)
}

// SymbolBuildContexts represents the build contexts that are associated with a
// SymbolMeta.
type SymbolBuildContexts struct {
	// builds are the build contexts that apply to this symbol.
	builds map[BuildContext]bool
}

// BuildContexts returns the build contexts for this UnitSymbol.
func (us *SymbolBuildContexts) BuildContexts() []BuildContext {
	var builds []BuildContext
	for b := range us.builds {
		builds = append(builds, b)
	}
	sort.Slice(builds, func(i, j int) bool {
		return builds[i].GOOS < builds[j].GOOS
	})
	return builds
}

// AddBuildContext adds a build context supported by this UnitSymbol.
func (us *SymbolBuildContexts) AddBuildContext(build BuildContext) {
	if us.builds == nil {
		us.builds = map[BuildContext]bool{}
	}
	if build != BuildContextAll {
		us.builds[build] = true
		return
	}
	for _, b := range BuildContexts {
		us.builds[b] = true
	}
}

// SupportsBuild reports whether the provided build is supported by this
// UnitSymbol. If the build is BuildContextAll, this is interpreted as this
// unit symbol supports at least one build context.
func (us *SymbolBuildContexts) SupportsBuild(build BuildContext) bool {
	if build == BuildContextAll {
		return len(us.builds) > 0
	}
	return us.builds[build]
}

// InAll reports whether the unit symbol supports all build contexts.
func (us *SymbolBuildContexts) InAll() bool {
	return len(us.builds) == len(BuildContexts)
}

// RemoveBuildContexts removes all of the build contexts associated with this
// unit symbol.
func (us *SymbolBuildContexts) RemoveBuildContexts() {
	us.builds = map[BuildContext]bool{}
}
